OAuth2.0 社交登录

OAuth2.0 社交登录流程(以github账号登录csdn为例)

在这里插入图片描述

  1. csdn 首先向用户请求 github 登录
  2. 用户点击 github 的登录按钮
    在这里插入图片描述
  3. 携带 client_id 跳转到 github 的登录页面,用户输入用户名和密码
  4. 当在 github 的登录页面输入用户名密码,点击登录按钮后
  5. 将登录信息提交到了 github 的授权服务器,授权服务器验证用户和密码,如果验证成功
  6. 将签发 code,根据重定向的 url 返回 csdn
  7. csdn 拿到返回 code 后,再加 client_id 和 client_secret(csdn 自己的 client_id和client_secret)再次请求授权服务器
  8. 授权服务器返回 token
  9. csdn获取到 github 签发的 token,此时 csdn 会携带 token 又一次向 github 发起请求,访问github的资源服务器
  10. 访问到 github 的资源服务器,并且根据上一步的请求,返回给csdn响应的信息,如用户的github的用户名,头像等

项目中加入 OAuth 2.0 登录功能

  1. 在 github 中注册一个OAuth 应用,地址
    在这里插入图片描述

  2. 填入相应的信息
    在这里插入图片描述

  3. 页面中加入如下代码:

    <a href="https://github.com/login/oauth/authorize?client_id=填写自己的clientid&response_type=code&redirect_uri=http://www.auth.mall.com/oauth2.0/github/success">
    	<img src="/static/login/img/github.png" />
    	<span>GitHub</span>
    </a>
    

    登录 github 成功后,github 网站会携带 code 跳转到该url http://www.auth.mall.com/oauth2.0/github/success,请根据自己的应用修改该 url 地址

  4. oauth2.0/github/success api

    @Slf4j
    @Controller
    public class OAuth2Controller {
    
        @Autowired
        MemberFeignService memberFeignService;
    
        @GetMapping("/oauth2.0/github/success")
        public String github(@RequestParam("code") String code, HttpSession session) throws Exception {
    
            // 1. 根据code换取accessToken
            Map<String, String> map = new HashMap<>();
            map.put("client_id", "在github上创建OAuth应用的id");
            map.put("client_secret", "应用的client_secret");
            map.put("code", code);
    
            Map<String, String> heards = new HashMap<>();
            heards.put("accept", "application/json");
            // 向github发送请求,换取token
            String url = "https://github.com/login/oauth/access_token";
            ObjectMapper objectMapper = new ObjectMapper();
            cn.hutool.http.HttpResponse httpResponse = HttpUtil
                    .createPost(url)
                    .header("Accept", "application/vnd.github.v3+json")
                    .body(objectMapper.writeValueAsString(map))
                    .execute()
                    .charset("utf-8");
            
            int statusCode = httpResponse.getStatus();
            if (statusCode == 200) {
                // {"access_token":"返回的token","token_type":"bearer","scope":""}
                GitHubOAuthTokenResult gitHubOAuthResult = JSON.parseObject(httpResponse.body(), GitHubOAuthTokenResult.class);
           		
                if (!getUserInfo(gitHubOAuthResult, session)) {
                    return "redirect:http://www.auth.mall.com/login.html";
                }
            } else {
                return "redirect:http://www.auth.mall.com/login.html";
            }
            // 2. 登录成功,跳回首页
            return "redirect:http://www.mall.com";
        }
       
        private boolean getUserInfo(GitHubOAuthTokenResult gitHubOAuthResult, HttpSession session) throws Exception {
    
            String url = "https://api.github.com/user";
            // 携带 access_token 访问 github 的开发api,如 https://api.github.com/user,获取用户信息
            cn.hutool.http.HttpResponse httpResponse = HttpUtil
                    .createGet(url)
                    .header("Accept", "application/vnd.github.v3+json")
                    .header("Authorization", "token " + gitHubOAuthResult.getAccess_token())
                    .execute()
                    .charset("utf-8");
            int status = httpResponse.getStatus();
            if (status == 200) {
                String resultStr = httpResponse.body();
                GitHubUserVo gitHubUserVo = JSON.parseObject(resultStr, GitHubUserVo.class);
                // 1) 当前用户如果是第一次进入,则自动注册(为当前社交用户生成一个会员信息帐号)
                // 登录或者注册这个社交用户
                GitHubUserFeignVo gitHubUserFeignVo = new GitHubUserFeignVo();
    
                BeanUtils.copyProperties(gitHubUserVo, gitHubUserFeignVo);
    
                gitHubUserFeignVo.setAccessToken(gitHubOAuthResult.getAccess_token());
                gitHubUserFeignVo.setSocialType(SocialType.GITHUB.getValue());
                gitHubUserFeignVo.setSocialUid(String.valueOf(gitHubUserVo.getId()));
    			// 将用户信息写入数据库
                R r = memberFeignService.githubOauthLogin(gitHubUserFeignVo);
                if (r.getCode() == 0) {
                    MemberRespVo member = r.getData("data", new TypeReference<MemberRespVo>() {});
                    log.info("登录成功:用户{}", member.toString());
                    session.setAttribute(AuthServerConstant.LOGIN_USER, member);
                    return true;
                }
            }
            return false;
        }
    }
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值