Java实现GitHub第三方登录详解

文章 未结 置顶 精帖 0 5.6k
无法显示用户头像
作者:ECode1024官方,责任编辑:ECode1024官方 5 钻石
发布于 2019-06-25
实现流程如下: 1.注册一个GitHub账号 2.注册一个授权的网站 保存一个你的Client ID和Client Secret 3.准备一个页面,有一个链接跳转到授权的页面 <a href="https://github.com/login/oauth/authorize?client_id=xx&state=STATE&redirect_uri=xx">GitHub登录</a> 4.准备controller去处理callback回调的请求 ① 获取到请求参数中的code ② 拿到code去发送请求请求token ③ 拿到token发送请求请求用户信息 ④ 将用户信息做持久化处理(放到请求范围中) ⑤ 在主页面通过el表单获取到前面取到的用户信息... OAuth2.0的认证原理 OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAUTH是安全的。oAuth是Open Authorization的简写,目前的版本是2.0版。  https://oauth.net/2 GitHub第三方登录的认证授权流程 申请 Client ID 和 ClientSecret 首先到GitHub官网注册账号: https://github.com/ img[https://newecode1024.oss-cn-hongkong.aliyuncs.com/ffcb61d4-851e-43cf-a0be-dd21b5026884.png]  登录:https://github.com/login img[https://newecode1024.oss-cn-hongkong.aliyuncs.com/71bb2ae2-aff8-4c23-bcd3-ce783a4d2192.png]  登录进去之后点击你的头像,选择Settings 选择左下方的Developer settings创建一个应用 img[https://newecode1024.oss-cn-hongkong.aliyuncs.com/edd34874-ad22-4916-961e-8060d44294f9.png]  img[https://newecode1024.oss-cn-hongkong.aliyuncs.com/d235b976-688c-48bb-8caa-222970c8779d.png]  注册应用之后,可以获取到 Client ID 和 Client Secret   img[https://newecode1024.oss-cn-hongkong.aliyuncs.com/0205d7d3-e286-4a72-9f50-7b1eb85cff60.png]  申请clientID和clientSecret的用途??? [pre] clientID:应用的唯一标识。 clientSecret:clientID对应的密钥,访问用户资源时用来验证应用的合法性。 申请地址: https://github.com/settings/developers 注意:对clientID和clientSecret信息进行保密,不要随意泄漏。 [/pre] GitHub的登录授权实现 [pre] 第三方登录流程是:先获取code --> 然后获取access_token --> 根据token获取用户信息。 前台页面实现步骤:点击登录按钮 --> 打开一个窗口,进行授权 --> 授权完成,跳转到首页或上次浏览的页面。 [/pre] 前台准备一个页面,有一个链接跳转到GitHub的授权页面 https://github.com/login/oauth/authorize?client_id=xx&state=xx&redirect_uri=xx 点击上面链接授权之后就会跳转到自己之前创建应用时设置的回调路径 img[https://newecode1024.oss-cn-hongkong.aliyuncs.com/0a76bc96-1de6-41b9-ae3a-9a82ccde78bf.png]  img[https://newecode1024.oss-cn-hongkong.aliyuncs.com/f880e2ec-96d1-4b0c-b386-49f2f094ee35.png]  登录就算完成了,那么我们怎么去获取用户信息来实现我们的其他功能呢??比如获取用户账号,头像等信息绑定到自己系统的数据库里面 代码实现   (温馨小提示:这里我将代码都一个文件了,有3个类,需要自己弄出来哦) 1.HttpClientUtils类: [pre] package cn.org.xinke.cloudguide.util; import com.alibaba.fastjson.JSONObject; import org.apache.http.HttpEntity; import org.apache.http.HttpStatus; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import java.util.HashMap; import java.util.Map; import java.util.Set; /**  * @description http请求发送工具类  * @author cinco  * @date 2019-6-25 13:02  */ public class HttpClientUtils {     /**      * 使用HttpClient发送一个Get方式的请求      *      * @param url 请求的路径,请求参数拼接到url后面      * @return 响应的数据      * @throws Exception      */     public static String doGet(String url)throws Exception{         CloseableHttpClient httpclient = HttpClients.createDefault();         HttpGet httpGet = new HttpGet(url);         // 发送一个http请求         CloseableHttpResponse response = httpclient.execute(httpGet);         // 如果响应成功,解析响应结果         if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){             // 获取响应的内容             HttpEntity responseEntity = response.getEntity();             return EntityUtils.toString(responseEntity);         }         return null;     }     // 参数的封装     public static Map<String, String> parseResponseEntity(String responseEntityStr){         Map<String,String> map = new HashMap<>();         String[] strs = responseEntityStr.split("\\&");         for (String str : strs) {             String[] mapStrs = str.split("=");             String value = null;             String key = mapStrs[0];             if(mapStrs.length>1){                 value = mapStrs[1];             }             map.put(key, value);         }         return map;     }     // json字符串转map     public static Map<String, String> parseResponseEntityJSON(String responseEntityStr){         Map<String,String> map = new HashMap<>();         // 解析json格式的字符串         JSONObject jsonObject = JSONObject.parseObject(responseEntityStr);         Set<Map.Entry<String, Object>> entries = jsonObject.entrySet();         for (Map.Entry<String, Object> entry : entries) {             String key = entry.getKey();             String value = String.valueOf(entry.getValue());             map.put(key, value);         }         return map;     } } [/pre] 2.GitHub常量类: [pre] package cn.org.xinke.cloudguide.constant; /**  * @description GitHub登录相关常量定义  * @author cinco  * @date 2019-6-25  */ public class GitHub {     /** Client ID */     public static final String CLIENT_ID = "xxx你的client_id";     /** Client Secret */     public static final String CLIENT_SECRET = "xxx你的client_secret";     /** Callback */     public static final String CALLBACK = "xxx你的callback地址"     /** 获取code的url */     public static final String CODE_URL = "https://github.com/login/oauth/authorize?client_id=CLIENT_ID&state=STATE&redirect_uri=CALLBACK";     /** 获取token的url */     public static final String TOKEN_URL = "https://github.com/login/oauth/access_token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&code=CODE&redirect_uri=CALLBACK";     /** 获取用户信息的url */     public static final String USER_INFO_URL = "https://api.github.com/user?access_token=TOKEN"; } [/pre] 3.GithubController类: [pre] package cn.org.xinke.cloudguide.controller; import cn.org.xinke.cloudguide.constant.GitHub; import cn.org.xinke.cloudguide.entity.User; import cn.org.xinke.cloudguide.service.UserService; import cn.org.xinke.cloudguide.util.HttpClientUtils; import cn.org.xinke.cloudguide.util.SessionUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Controller; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.annotation.Resource; import javax.servlet.http.HttpSession; import java.util.Map; /**  * @description GitHub登录  * @author cinco  * @date 2019-6-25 中午 12:42  */ @Slf4j @Controller public class GithubController {     /**      * 登录回调      *      * @param code      * @param session      * @throws Exception      */     @RequestMapping("/callback")     public String callback (@RequestParam("code") String code) throws Exception {         if(!StringUtils.isEmpty(code)){             // 拿到我们的code,去请求token             String token_url = GitHub.TOKEN_URL.replace("CLIENT_ID", GitHub.CLIENT_ID)                     .replace("CLIENT_SECRET", GitHub.CLIENT_SECRET)                     .replace("CALLBACK", GitHub.CALLBACK)                     .replace("CODE", code);             log.info("用户信息数据: " + token_url);             String responseStr = HttpClientUtils.doGet(token_url);             String token = HttpClientUtils.parseResponseEntity(responseStr).get("access_token");             // 根据token发送请求获取登录人的信息             String userinfo_url = GitHub.USER_INFO_URL.replace("TOKEN", token);             responseStr = HttpClientUtils.doGet(userinfo_url);             Map<String, String> responseMap = HttpClientUtils.parseResponseEntityJSON(responseStr);             log.info("登录用户信息:" + responseMap);             log.info("获取登录用户的用户名:" + responseMap.get("login"));             log.info("获取登录用户的头像地址: " + responseMap.get("avatar_url"));         }         // 跳转到你想去的页面         return "redirect:/";     } } [/pre] maven项目中还需要额外引入如下: [pre] <!-- GitHub第三方登录所需 --> <dependency>       <groupId>org.apache.httpcomponents</groupId>       <artifactId>httpclient</artifactId>       <version>4.5.6</version> </dependency> <dependency>       <groupId>com.alibaba</groupId>       <artifactId>fastjson</artifactId>       <version>1.2.47</version> </dependency> [/pre]

声明:本文所有观点仅代表创作者本人,ECode1024系信息收集发布平台,ECode1024仅提供信息存储以及展示服务。若有侵权,请联系我们删除。
回复
  • 暂无任何回复,抢个沙发吧~~
推荐阅读
layui

微信扫码关注 ECode1024 公众号带给你更多优质内容