前言
因为年前换工作(新工作也没之前那么闲了)以及过年的原因,评论功能的开发进度一直很慢,一点一点的也算是完成了一部分功能,这次先写第一篇关于GitHub账号OAuth授权的过程,之后会再写授权之后如何评论以及评论回复之类的。
16年写第一个博客的时候,评论时只需要输入昵称以及邮箱即可。这次考虑了下,还是使用GitHub的账号来进行访客用户的管理比较好,顺便练下这类授权登录(QQ、微信等第三方账号授权登录类似)。
源码
前端页面: Talk is cheap.
后端接口: Show me the code.
GitHub授权过程
1. 在自己的GitHub中注册OAuth Apps。
2.点击触发登录,跳转到授权页面
// components/Comment.vue 页面
githubLogin: function () {
window.location.href = 'https://github.com/login/oauth/authorize?client_id=6625cb27769b1bc52415&redirect_uri=http://localhost:3000/login&scope=user:email';
window.localStorage.setItem('GITHUB_LOGIN_REDIRECT_URL', `${this.$route.path}?comment=new`);
}
其中:https://github.com/login/oauth/authorize
是需要跳转的授权地址,client_id
和redirect_uri
都是在GitHub设置中的内容,保持一致即可。scope
是获取用户信息的范围,更多的值可以参考官方文档。
localStorage
中存储当前页面的地址,是为了后续授权登录成功之后跳转到当前的页面,comment=new
参数是为了与正常访问的当前页面作区分。
4. 跳到官方提供的授权页面
5. 确认授权后会跳转到http://localhost:3000/login?code=aa043845e6b80253919f
页面
跳转到login
页面是为了显示等待页面,同事为了存储后续接口的返回值,并进行相应的跳转。最开始是之前跳转到一个接口的,但处理起来会更麻烦一些。
// pages/login.vue 页面
mounted () {
return axios.get(`/oauth/github/github_oauth?code=${this.$route.query.code}`).then(res => {
if (res.data.success === 1) {
let guest = {
userName: res.data.userName,
avatar: res.data.avatar
};
window.localStorage.setItem('GITHUB_LOGIN_TOKEN', res.data.token);
window.localStorage.setItem('GITHUB_LOGIN_GUEST', JSON.stringify(guest));
let redirectUrl = window.localStorage.getItem('GITHUB_LOGIN_REDIRECT_URL');
this.$router.push({ path: redirectUrl });
}
});
}
6. 后端接口根据返回的code值处理授权
此处需要在后端中发起两个请求:
1.第一个请求用来获取到用户授权后的access_token
2.第二个请求会根据第一个请求获取到的access_token
来取得用户信息
// server/api/oauth/github.controller.js
exports.githubOAuth = async(ctx) => {
const code = ctx.query.code;
let path = 'https://github.com/login/oauth/access_token';
const params = {
client_id: config.oAuth.github.client_id,
client_secret: config.oAuth.github.client_secret,
code: code
};
await fetch(path, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
})
.then(res => {
return res.text();
})
.then(body => {
const args = body.split('&');
let arg = args[0].split('=');
return arg[1];
})
.then(async(token) => {
const url = ' https://api.github.com/user?access_token=' + token;
await fetch(url)
.then(res => {
return res.json();
})
.then(async(res) => {
let userId = 0;
/**
* 用户保存过程,有需要可查看源码
*/
if (userId > 0) {
ctx.session.user = res.login;
// 用户token
const userToken = {
name: res.login,
id: userId
};
// 签发token
const token = jwt.sign(userToken, config.tokenSecret, { expiresIn: '2h' });
ctx.body = {
success: 1,
token: token,
userName: res.login,
avatar: res.avatar_url,
message: ''
};
} else {
ctx.body = {
success: 0,
token: '',
message: 'GitHub授权登录失败'
};
}
});
})
.catch(e => {
console.log(e);
ctx.body = {
success: 0,
token: '',
message: 'GitHub授权登录失败'
};
});
};
总结
经过以上几个步骤,GitHub的授权流程已经走完,这时我们的数据库中也保存下了用户的一些信息,就可以继续进行之后评论的操作了。