Loading

前后端分离下的第三方登录

大致流程(授权码模式)

以码云为例

获取用户请求的API需要在请求中携带授权码

而授权码的获取涉及OAuth2认证

  • 首先是用户点击链接跳转到码云的授权页面
    跳转链接需要将{client_id}{redirect_uri}替换为您在码云中注册第三方应用时填写的信息

    response_type指定为授权码模式(code)
    https://gitee.com/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code
    

    回调地址最好上填成前端的,前端拿到code之后再发请求给spring应用

    用户同意授权之后,码云会通过回调地址将用户授权码code发送给我们。
    也就是一个带参数的get请求,可以使用searchParams从浏览器地址栏中获取它

    const urlParams = new URL(window.location.href)
    const code = urlParams.searchParams.get("code")
    

    回调地址记得填写成前端,如果回调地址填了后端,由后端去主动通知web还是比较麻烦的。(当然你可以使用websocket)

  • 根据获取到的授权码(code)申请access_token
    这一步因为需要填充client_secret,所以我们可以让前端发送http请求给spring服务。让spring带上code以及secret去获取access_token

      https://gitee.com/oauth/token?grant_type=authorization_code&code={code}&client_id={client_id}&redirect_uri={redirect_uri}&client_secret={client_secret}
    
  • 带上上一步获得的授权码请求用户基本信息

      https://gitee.com/api/v5/user?access_token={your_token}
    

    根据您应用的规则去查询数据库,返回给前端相应的用户信息

部分代码

  •   @Controller
      @CrossOrigin(originPatterns = "*", methods = {RequestMethod.GET, RequestMethod.POST})
      public class ThirdPartyLoginController {
        @Autowired
        private PrividerToken prividerToken;
        // 可以根据平台的不同从配置中读取
        String clientId = "123";
        String clientSecret = "123";
        String redirectUri = "http://callBack.com";
    
        @GetMapping("/thirdLoad")
        @ResponseBody
        public String callback(@RequestParam("code") String code
        ) throws IOException {
    
          prividerToken.setClientSecret(clientSecret);
          prividerToken.setClientId(clientId);
          prividerToken.setCode(code);
          String url = "https://gitee.com/oauth/token?grant_type=authorization_code"
                  + "&code=" + code
                  + "&client_id=" + prividerToken.getClientId()
                  + "&redirect_uri=" + prividerToken.getRedirectUri()
                  + "&client_secret=" + prividerToken.getClientSecret();
    
          MediaType mediaType
                  = MediaType.get("application/json; charset=utf-8");
    
          OkHttpClient client = new OkHttpClient();
          RequestBody body = RequestBody.create(JSON.toJSONString(prividerToken), mediaType);
          Request request = new Request.Builder()
                  .url(url)
                  .post(body)
                  .build();
    
          try (Response response = client.newCall(request).execute()) {
              String res = response.body().string();
              String split = res.split(":")[1];
              String accessToken = split.split("\"")[1];
              User userInfo = getUserInfo(accessToken);
              return String.valueOf(userInfo.getId());
          }
    
      }
    
      private User getUserInfo(@org.springframework.web.bind.annotation.RequestBody String accessToken) {
          OkHttpClient client = new OkHttpClient();
          String url = "https://gitee.com/api/v5/user?access_token=" + accessToken;
          Request request = new Request.Builder()
                  .url(url)
                  .build();
          User user = null;
          try (Response response = client.newCall(request).execute()) {
              String string = response.body().string();
              user = JSON.parseObject(string, User.class);
              System.out.println(user);
          } catch (IOException e) {
              e.printStackTrace();
          } finally {
              return user;
          }
      }
    }
    
  •       const urlParams = new URL(window.location.href)
          const code = urlParams.searchParams.get("code")
          if(code){
            $.ajax({
              url:'http://localhost:8080/thirdLogin?code='+code,
              method:'get',
              success:(res)=>{
                alert(res);
                console.log(res)
              }
            })
          }
    

如何在码云上申请第三方应用登录

  • 点击头像,进入设置
  • 在侧边栏中选择第三方应用

参考

posted @ 2021-07-16 18:30  AD_milk  阅读(1680)  评论(0编辑  收藏  举报