前后端分离 github登录(Oauth2)
第三方登录在前后端不分离的情况下实现比较简单,在前后端分离情况下思路相同但是实现相对复杂。
复杂点:
- 生成token
- 把token和用户数据给前端页面
第一点如果熟悉token、JWT并不算复杂,主要是第二点容易卡住,需要应用前端知识。
将token和用户数据给前端
可能没有试过的同学不知道难在哪里,看一下登录逻辑图就知道难在哪了。
后端想返回数据可是前端没有监听后端的响应,前端只能获取GitHubAPP的响应,但是没有。
那如何做呢?
具体实现:前端
前端 vue
github_login() {
var githubUrl =
"githubapp url";
// 弹出 500 * 500 的窗口
window.open(
githubUrl,
"newwindow",
"height=500, width=500, top=0, left=0, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=n o, status=no"//style不重要
);
// 通过监听小窗口,父页面可以拿到子页面(小窗口)发送给父页面的消息,父(前端页面),子(小窗)
window.addEventListener(
"message",//监听事件类型
function (e) {//e里面有我们需要的数据
console.log(e.data);//打印看一下有没有的到
},
false
);
},
参考https://www.jianshu.com/p/da54bad42b30,感谢!
但是主要后端return的数据window.addEventListener监听不到!!!
后端给的数据会显示在小窗上,但那个数据小窗口没有发送!!!
注释写了,父页面监听子页面发送给父页面的消息。
如何发送!通过JavaScript!
所以后端应该返回到一个中间页面或者返回html!
具体实现:后端
后端部分代码
public String githubLogin(@RequestParam("code")String code, @RequestParam("state")String state) throws Exception {
String accessToken = gitHubLoginProvider.getAccessToken(code);//获得github_token
GitHubUserDTO gitHubUserDTO= gitHubLoginProvider.getUserInfo(accessToken);//获得user_message gitHubLoginProvider.getUserInfo(accessToken)是封装的函数,大家在写的时候自己封装一下,或者等下一篇博客(doge)
UserAuths userAuths=userAuthsService.getOneByUserIdAndIdentityType(gitHubUserDTO.getId(),2);//封装到自己的实体类
String token= JwtUtils.createTokenNow(gitHubUserDTO.getId(),2);//生成自己的token
//返回的数据
Map<String,String> result=new HashMap<>();
result.put("token",token);
// vue前端获取这个数据,去登录。
String html = "<head>\n" +
" <meta charset=\"UTF-8\">\n" +
"</head>\n" +
"<body>\n" +
" <p style=\"text-align: center;\"><h3>登录中....</h3></p>\n" +
"</body>" +
"\n" +
"<script>\n"+
" window.οnlοad=function () {\n" +
" var message =" + JSONUtil.toJsonStr(result) + ";\n" +
" window.opener.postMessage(message, 'http://localhost:8089/bbs/login');\n" +//url是父页面的url
" window.close();\n" +
" }\n" +
"</script>\n"+
"\n";
return html;
}
window.opener.postMessage是JavaScript发送消息的函数。
这个window可以理解成小窗口运行这段html+JavaScript,再打开一个小窗口,在小窗口的小窗口发消息给父页面,总之这样就可以接收到token了。
我对js并不了解只是会用,如有错误欢迎指正。
参考:
https://www.jianshu.com/p/da54bad42b30
感谢