串接OAuth登入流程
綜觀流程:
1. 登入按鈕按下去後導至第三方頁面登入並且把資料待在URL上面
2. 第三方驗證獲取資料
3. 導回指定頁面並且把資料帶在URL上面
設定檔案
const config = {
// 请求授权地址
userAuthorizationUri: `${process.env.VUE_APP_OAUTH_BASEURI}/connect/authorize`,
// accessToken请求地址
accessTokenUri: `${process.env.VUE_APP_OAUTH_BASEURI}/connect/token`,
// 用户信息请求地址
userInfoUri: `${process.env.VUE_APP_OAUTH_BASEURI}/connect/userinfo`,
// 登出请求地址
logoutUri: `${process.env.VUE_APP_OAUTH_BASEURI}/connect/endsession`,
// 项目地址
localuri: process.env.VUE_APP_OAUTH_LOCALURI,
// 回调地址
redirect_uri: `${process.env.VUE_APP_OAUTH_LOCALURI}/oauthloading`,
// 案例资源服务器地址
resUri: '',
// 客户端相关标识,请从认证服务器申请
client_id: process.env.VUE_APP_OAUTH_CLIENT_ID,
client_secret: '',
// 申请的权限范围
// scope: 'offline_access+openid+profile+PlmAPI+role+email+phone',
scope: 'openid+profile+PlmAPI+email',
// scope: '',
// 可选参数,客户端的当前状态,可以指定任意值,用于校验,此次案例不做相关认证
state: '',
// 一些固定的请求参数
response_type: 'code',
grant_type: 'authorization_code',
code: ''
}
// response_type:表示授权类型,必选项,此处的值固定为"code"
// client_id:表示客户端的ID,必选项
// redirect_uri:表示重定向URI,可选项
// scope:表示申请的权限范围,可选项
// state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
export default config
使用策略模式來管理登入
import { delCookie, getCookie } from './cookie.js'
import { encode } from 'js-base64'
export const strategies = {
defaultLogIn (token, ecode) { //普通的登入
window.document.cookie = `token=${token}; path=/`
ecode = encode(ecode)
window.document.cookie = `ecode=${ecode}; path=/`
return { can: true, uri: '' }
},
uriLogIn (token, ecode) { //信箱連結需要用到的登入
const urlParams = new URLSearchParams(window.location.search)
const urlParamsFormat = new URLSearchParams(urlParams.get('state'))
const uri = window.decodeURI(window.decodeURIComponent(urlParamsFormat.get('uri')) + `&ecode=${encode(ecode)}`)
window.location.href = uri
return { can: false, uri: '' }
},
PCASignLogIn (token, ecode) {
window.document.cookie = `token=${token}; path=/`
ecode = encode(ecode)
window.document.cookie = `ecode=${ecode}; path=/`
const urlParams = new URLSearchParams(window.location.search)
const urlParamsFormat = new URLSearchParams(urlParams.get('state'))
const id = window.decodeURI(window.decodeURIComponent(urlParamsFormat.get('Sign')))
return { can: true, uri: `/PLM/PCA/${id}` }
}
}
export const oauth = {
canLogin (grantedPolicies) {
return Object.keys(grantedPolicies).some(str => str.includes('MenuManagement'))
},
oauthLogin (grantedPolicies, token, email) {
const strategy = this.loginController()
if (strategy === 'defaultLogIn') {
if (this.canLogin(grantedPolicies)) {
return strategies[strategy](token, email)
}
} else {
return strategies[strategy](token, email)
}
},
loginController () {
if (window.location.search.includes('uri')) {
return 'uriLogIn'
}
if (window.location.search.includes('Sign')) {
return 'PCASignLogIn'
}
return 'defaultLogIn'
},
loadEcode () {
return getCookie('ecode') ? getCookie('ecode') : false
},
loggedIn () {
return !!(getCookie('ecode') && getCookie('token'))
},
logOut (Vue) {
delCookie('ecode')
delCookie('token')
delCookie('empNo')
delCookie('userName')
delCookie('originEmpNo')
delCookie('originUserName')
Vue.$router.push('/')
}
}
參考資料: