GitHub第三方登录实现效果如下:
实现流程如下:
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/
登录进去之后点击你的头像,选择Settings
选择左下方的Developer settings创建一个应用
注册应用之后,可以获取到 Client ID 和 Client Secret
申请clientID和clientSecret的用途???
clientID:应用的唯一标识。
clientSecret:clientID对应的密钥,访问用户资源时用来验证应用的合法性。
申请地址: https://github.com/settings/developers
注意:对clientID和clientSecret信息进行保密,不要随意泄漏。
GitHub的登录授权实现
第三方登录流程是:先获取code --> 然后获取access_token --> 根据token获取用户信息。
前台页面实现步骤:点击登录按钮 --> 打开一个窗口,进行授权 --> 授权完成,跳转到首页或上次浏览的页面。
前台准备一个页面,有一个链接跳转到GitHub的授权页面
https://github.com/login/oauth/authorize?client_id=xx&state=xx&redirect_uri=xx;
点击跳转到GitHub第三方登录页面
登录账号进行授权
授权之后就会跳转到自己之前创建应用时设置的回调路径
温馨小提示:如果是本地测试可将回调地址修改成本地路径
温馨小提示:可在GitHub上 https://github.com/settings/applications 取消授权的应用
登录就算完成了,那么我们怎么去获取用户信息来实现我们的其他功能呢??比如获取用户账号,头像等信息绑定到自己系统的数据库里面
代码实现 (温馨小提示:这里我将代码都一个文件了,有3个类,需要自己弄出来哦)
package com.zhengqing.web.controller;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
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 org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@Controller
public class GitHubCallBackController {
//授权成功后的回调,我们需要在这个方法中拿到code去请求token
@RequestMapping("/callback")
public String callback(String code, String state) throws Exception{
//获取到code和state
System.out.println("code:"+code);
System.out.println("state:"+state);
if(!StringUtils.isEmpty(code)&&!StringUtils.isEmpty(state)){
//拿到我们的code,去请求token
//发送一个请求到
String token_url = GitHubConstants.TOKEN_URL.replace("CLIENT_ID", GitHubConstants.CLIENT_ID)
.replace("CLIENT_SECRET", GitHubConstants.CLIENT_SECRET)
.replace("CALLBACK", GitHubConstants.CALLBACK)
.replace("CODE", code);
// System.out.println("用户信息数据"+token_url);//这个里面有我们想要的用户信息数据
String responseStr = HttpClientUtils.doGet(token_url);
String token = HttpClientUtils.parseResponseEntity(responseStr).get("access_token");
//根据token发送请求获取登录人的信息
String userinfo_url = GitHubConstants.USER_INFO_URL.replace("TOKEN", token);
responseStr = HttpClientUtils.doGet(userinfo_url);//json
Map<String, String> responseMap = HttpClientUtils.parseResponseEntityJSON(responseStr);
System.out.println("登录用户信息:"+responseMap);//responseMap里面保存着用户登录信息
System.out.println("获取登录用户的用户名:"+responseMap.get("login"));
}
return "main";// TODO 修改成自己需要返回的页面...
}
}
//抽取出来的参数【代码拷贝下来只需要修改成自己的CLIENT_ID,Client CLIENT_SECRET,CALLBACK即可】
class GitHubConstants {
public static final String CLIENT_ID = "xx"; // TODO 修改成自己的
public static final String CLIENT_SECRET = "xx"; // TODO 修改成自己的
public static final String CALLBACK = "xx"; // TODO 修改成自己的 [注意:callback要和注册的回调路径保持一致 否则登录授权之后会报NullPointerException]
//获取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";
}
//工具类
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);
CloseableHttpResponse response = httpclient.execute(httpGet); //发送一个http请求
//如果响应成功,解析响应结果
if(response.getStatusLine().getStatusCode()==200){
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<>();
JSONObject jsonObject = JSONObject.parseObject(responseEntityStr); //解析json格式的字符串
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;
}
}
maven项目中还需要额外引入如下,其余的就是自己项目的配置,比如上面的代码是springmvc配置通过 @Controller 进行跳转...
<!-- 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>
可直接拷贝到自己的项目中使用哦,注意修改以下部分哦
以及注意这个 responseMap 里面封装了我们想要的用户信息数据哦
ex:repos_url里面有很多我们想要的数据
代码最后运行结果: 可根据自己的需求去拿数据