- 前端异步调用后端接口
/api/oauth/github
GoGithub () {
this.$rest.auth.github().then(res => {
console.log(res)
window.location.href = res
})
}
- 后端配置参数,并将github授权页面的地址返回给前端(以 koa 代码为例)
const GetGithub = async ctx => {
let dataStr = (new Date()).valueOf()
// 重定向到认证接口,并配置参数
// https://github.com/login/oauth/authorize?client_id=xxxxx&state=xxx&redirect_uri=xxxx
let path = 'https://github.com/login/oauth/authorize'
path += '?client_id=' + OAuthConfig.GITHUB_CLIENT_ID
// path += '&scope=' + OAuthConfig.GITHUB_CLIENT_SCOPE
path += '&state=' + dataStr
ctx.body = path
}
- 前端跳转到github授权页面

- 前端授权成功,页面会跳转到预先设置好的后端回掉地址

地址中会携带code
http://www.bipubipu.com/api/oauth/github/callback?code=14de2c737aa02037132d&state=1496989988474
- 后端利用
code交换accessToken,并将页面重定向到前端指定的登陆后页面(网站主页),路径中包含accessToken(是否替换为session_id?)
const GetGithubAccessToken = async (ctx, next) => {
var code = ctx.request.query.code
var path = 'https://github.com/login/oauth/access_token'
path += '?client_id=' + OAuthConfig.GITHUB_CLIENT_ID
path += '&client_secret=' + OAuthConfig.GITHUB_CLIENT_SECRET
path += '&code=' + code
let accessToken = ''
await rp.post(path).then(body => {
// console.log('body', body)
let obj = url.getSearch(body)
accessToken = obj.access_token
})
ctx.redirect(`http://localhost:8080/#/github?access_token=${accessToken}`)
}
- 前端将
accessToken作为参数调用后端接口/api/oauth/github/user,获取需要的用户信息(头像)
getData () {
let params = {
token: this.$route.query.access_token
}
this.$rest.auth.getGithubUser(params).then(res => {
if (res.success) {
this.user = res.data
console.log(res)
}
})
}
- 后端用
accessToken向github发起请求,获得用户信息,返回给前端
const GetGithubUser = async (ctx, next) => {
let result = {
success: false,
data: null
}
var path = 'https://api.github.com/user'
var opts = {
uri: path,
qs: {
access_token: ctx.query.token // -> uri + '?access_token=xxxxx%20xxxxx'
},
headers: {
'User-Agent': 'Request-Promise'
},
json: true
}
await rp.get(opts).then(res => {
result.data = res
result.success = true
}).catch(err => {
ctx.body = err
return false
})
ctx.body = result
}
- 前端加载用户头像

个人疑问:
- session_id在哪一步传回来,我们是通过sessionl_id来换取相应的用户信息吗
- 要不要给前端
accessToken - 在个人页面需要加载个人的谱册和收藏的谱册,是前端还是后端来判断
- 在单个谱册页面是否有编辑权限,是前端还是后端来判断
接口名参考:
router.get('/api/oauth/github', GetGithub)
router.get('/api/oauth/github/callback', GetGithubAccessToken)
router.get('/api/oauth/github/user', GetGithubUser)