JAVA-网站应用接入GitHub第三方登录
相对 网站应用接入 QQ 登录,简单很多,Github 直接创建应用就可以用,不需要长时间的审核
GitHub 开发者官方文档:https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/
(一)准备,创建应用
(1)开打开发者(不需要审核)
访问:https://github.com/settings/profile
(2)创建应用
(3)填写信息
(二)前台页面
一行就够
login.html 源代码:
<a href="account/github/login">Github 登录</a>
(三)后台处理流程
(1)前端请求登录,无参数
(2)后端重定向到
地址:https://github.com/login/oauth/authorize
参数:client_id=(AppID)
redirect_uri=(回调地址)
state=(原样返回)
返回时
code=(授权码)
state=(原样返回)
(3)返回回调地址,通过 Authorization Code 获取 AccessToken
请求地址:https://github.com/login/oauth/access_token
参数:client_id=(AppId)
client_secret=(密钥)
code=(回调地址携带的 code)
redirect_uri=(回调地址,和上面回调地址一样)
返回时
access_token=(访问授权码)
token_type=bearer(固定)
(4)通过 access_token 获取用户信息
请求地址:https://api.github.com/user
参数:access_token(返回的访问授权码)
(四)后台操作
/**
* <p>
* Github 登录 前置控制器
*
* @author java997.com
* @since 2019-05-25
*/
@Controller
@RequestMapping("/account/github")
public class GithubLoginController {
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String githubLogin() {
String githubState = "adgasgdsdhgi";
return "redirect:https://github.com/login/oauth/authorize?client_id=9431d36ea5ad14a5d9c4&redirect_uri=http://127.0.0.1:8080/account/github/callback&state=" + githubState;
}
@RequestMapping(value = "/callback", method = RequestMethod.GET)
@ResponseBody
public String githubCallback(String code, String state) {
System.out.println("==>state:" + state);
System.out.println("==>code:" + code);
// Step2:通过 Authorization Code 获取 AccessToken
String githubAccessTokenResult = HttpUtil.sendGet("https://github.com/login/oauth/access_token",
"client_id=9431d36ea5ad14a5d9c4&client_secret=05bf2b7a8f207d0dd1100ae119a0a66412fb7d5b&code=" + code +
"&redirect_uri=http://127.0.0.1:8080/account/github/callback");
System.out.println("==>githubAccessTokenResult: " + githubAccessTokenResult);
/**
* 以 & 为分割字符分割 result
*/
String[] githubResultList = githubAccessTokenResult.split("&");
List<String> params = new ArrayList<>();
// paramMap 是分割后得到的参数对, 比说 access_token=ad5f4as6gfads4as98fg
for (String paramMap : githubResultList) {
if (!"scope".equals(paramMap.split("=")[0])){
// 再以 = 为分割字符分割, 并加到 params 中
params.add(paramMap.split("=")[1]);
}
}
//此时 params.get(0) 为 access_token; params.get(1) 为 token_type
// Step2:通过 access_token 获取用户信息
String githubInfoResult = HttpUtil.sendGet("https://api.github.com/user","access_token="+params.get(0));
return githubInfoResult;
}
}
(五)工具类
httpUtil.java 源代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Map;
import java.io.PrintWriter;
import java.util.List;
/**
* <p>
* Http 请求工具类
*
* @author java997.com
* @since 2019-05-25
*/
public class HttpUtil {
/**
* 向指定 URL 发送 GET 方法的请求
*
*
* @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return URL 所代表远程资源的响应结果
*/
public static String sendGet(String url, String param) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = url + "?" + param;
URL realUrl = new URL(urlNameString);
// 打开和 URL 之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader 输入流来读取 URL 的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送 GET 请求出现异常!" + e);
// logger.error("连接出错",e);
}
// 使用 finally 块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
// logger.error("连接出错",e2);
}
}
return result;
}
/**
* 向指定 URL 发送 POST 方法的请求
*
* @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String url, String param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
OutputStream outputStream = conn.getOutputStream();
String aa = new String(param.getBytes("UTF8"),"UTF8");
System.out.println("=========== "+aa);
out = new PrintWriter(outputStream);
// 发送请求参数
out.print(aa);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!"+e);
//logger.error("连接出错",e);
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
ex.printStackTrace();
}
}
return result;
}
}
(六)测试
会回到唯一 id 和一些基本资料: