紧接上一篇的阿里云短信验证登录之后,今天我们来完成通过github的授权登录功能。 SpringBoot接入阿里云短信服务,实现登录验证功能
还请多多关注我的公众号:前端进阶攻城狮
每周固定更新技术分享
或者来到我的博客进行留言 Cc技术人生
OAuth App
首先进入到github,通过右上角进入到Setting,再最底下找到Developer Settings
创建一个授权信息
填写应用名称、首页地址以及回调地址
这里的回调地址指的是当通过github授权拿到code后去请求的地址
这里的地址与后端接口路由保持一致,在开发阶段还请写成本地,线上再进行更换。
创建成功后会给到一个ClientID以及secret,secret只能看一次,还请保存下来
准备工作已经完毕,接下来开始编写代码
跳转授权页
js
const githubClick = () => {
window.location.href =
'https://github.com/login/oauth/authorize?client_id=xxxxxx&redirect_uri=http://xxxxxxxxxxx/github/login&state=785895&scope=user'
}
在点击github登录时跳转到指定的路径https://github.com/login/oauth/authorize
拼接上之前拿到的client_id
以及回调地址
state
:不可猜测的随机字符串 随便给
scope
:授权作用域 给user就行了
跳转后来到 这样的一个页面
点击绿色的授权按钮后,通过刚才填写的回调地址,收到到传来的code
后端逻辑
首先,我们现在配置文件中配置好之前已经拿到的几样数据
yml
github:
clientId: c3xxxxxxxxxxx239
clientSecret: 77xxxxxxxxxxxxxxxxxxx46fc
redirectURI: http://xxxxxxxxxxxxx/user/github/login
authorizeURL: https://github.com/login/oauth/authorize
accessToken: https://github.com/login/oauth/access_token
userInfo: https://api.github.com/user
这里的clientId、clientSecret、redirectURI根据实际填写
添加GithubConfig类
java
@Data
@Component
@ConfigurationProperties(prefix = "github")
public class GithubConfig {
private String clientId;
private String clientSecret;
private String redirectURI;
private String authorizeURL;
private String accessToken;
}
然后,我们通过回调拿到code参数,在controller添加方法
java
@GetMapping("/github/login")
public RedirectView githubLogin(@RequestParam("code") String code){
return new RedirectView(userService.githubLogin(code));
}
最终返回一个重定向地址
我们去实现githubLogin这个方法
java
@Override
public String githubLogin(String code) {
//1.code参数为github回调callback_uri时,github传递过来的
System.out.println("请求callback...,code:"+code);
AccessTokenParam param = new AccessTokenParam();
param.setClient_id(githubConfig.getClientId());
param.setClient_secret(githubConfig.getClientSecret());
param.setCode(code);//传入code参数
param.setRedirect_uri(githubConfig.getRedirectURI());
//获取access token
String json= JSON.toJSONString(param);
//2.根据传入的参数(包含code),post请求https://github.com/login/oauth/access_token,获取返回值
String result= httpHelper.Post(githubConfig.getAccessToken(),json);//access_token=your_client_id&scope=user&token_type=bearer
System.out.println( "callback result:"+result);
String[] strs=result.split("&");
String access_token=strs[0].split("=")[1];//解析access_token
System.out.println("access_token:"+access_token);
//3.根据access token,请求https://api.github.com/user获取用户信息
String userInfo=httpHelper.Get(githubConfig.getUserInfo(),access_token);
System.out.println("userInfo:"+userInfo);//返回的是一个json字符串
GithubUser user = JSON.parseObject(userInfo, GithubUser.class);
User user1 = this.getById(user.getId());
if(user1==null){
User myUser = new User();
myUser.setUsername(user.getName());
myUser.setId(user.getId());
this.save(myUser);
}
return "http://127.0.0.1:3000/?userId="+user.getId();
}
最后的业务中判断当前id是否已存在,若是新用户进行入库处理,最终返回携带用户id的url地址进行页面重定向。
前端获取用户信息
当url上携带userId时,前端进行数据的获取
js
const {setUserInfo,userInfo} = useUserStore();
const fetchGithubUserInfo = async (id: string) => {
const res = await queryUser(id);
setUserInfo(res)
}
useEffect(() => {
if(search.get('userId')&&!userInfo.id){
fetchGithubUserInfo(search.get('userId')!)
}
},[search.get('userId')])
这里通过全局状态进行存储并使用了本地存储,做了一些数据判断减少不必要的请求。