1. 概述
-
本例將在上一個實例基礎上實現純js客戶端認證,使用vue-cli 腳手架創建客戶端app.
-
使用oidc-client.js 組件,默認使用cookie 保存客戶端憑據。
2. 服務端添加Client
純js客戶端需要新增一個client,並需要顯式聲明允許瀏覽器url 傳遞accesstoken,Conig 類新增代碼如下:
new Client
{
ClientId="js",
ClientName="vue Client",
RequireConsent=false,
AllowAccessTokensViaBrowser=true,
AllowedGrantTypes= GrantTypes.Implicit, // 隱式授權碼
RedirectUris={"http://localhost:8080/callback"},
PostLogoutRedirectUris={"http://localhost:8080/logout"},
AllowedScopes= new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile
}
}
3. Vue客戶端
3.1 准備vue client 工程項目
// 使用vue-cli 腳手架創建工程
vue create authclient
// 引用router 組件
npm isntall vue-router --s
// 引用oidc-client 組件
npm install oidc-client --s
3.2 創建兩個頁面組件(home & callback)
import Vue from 'vue'
import Router from 'vue-router'
import callback from '@/pages/callBack.vue'
import home from '@/pages/home.vue'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [{
path: '/',
component: home,
},
{
path:'/callback',
name:'callback',
component:callback
}
]
})
3.3 創建路由頁面組件
// home
<template>
<div class="hello">
<h1>home page</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
// callback
<template>
<div>callback</div>
</template>
<script>
export default {
name: 'callback',
mounted() {
this.$userManager.signinRedirectCallback().then(
(u) => {
console.log(u);
window.history.replaceState(
{},
window.document.title,
window.location.origin + window.location.pathname
);
window.location = '/';
},
(error) => {
console.log(error);
}
);
},
};
</script>
3.4 添加sso 組件,用於配置oidc客戶端
import Oidc from 'oidc-client'
const host = location.origin
const authsServer = 'http://localhost:5010'
const userManager = new Oidc.UserManager({
authority: authsServer, // server 地址
client_id: 'js', // client id
post_logout_redirect_uri: `${host}/logout`, // 退出登錄
redirect_uri: `${host}/callback`,
silent_redirect_uri: `${host}/callback`,
accessTokenExpiringNotificationTime: 4, // 超時
silentRequestTimeout: 2000, //
response_type: 'token id_token',
scope: 'openid profile',
filterProtocolClaims: true
})
userManager.events.addUserSignedOut(() => {
userManager.removeUser().then(() => {
userManager.signinRedirect().catch(()=>{
console.error('error wihile logout')
})
})
})
export default userManager;
3.5 main.js 注冊oidc 和路由
import Vue from 'vue'
import App from './App.vue'
import userManager from './sso.js'
import router from './router.js'
Vue.config.productionTip = false
Vue.prototype.$userManager = userManager
router.beforeEach(async (to, from, next) => {
if (to.name === 'callback') {
next()
} else if (to.name === 'logout') {
console.log('log out....')
} else {
const user = await userManager.getUser();
if (user) {
next()
}
else {
userManager.signinRedirect().catch(error => {
console.error(error)
})
}
}
})
new Vue({
router,
render: h => h(App),
}).$mount('#app')
最終項目目錄如下:
4. 啟動調試
- 先啟服務器,再啟客戶端,此時客戶端路由攔截器會重定向到localhost:5010 登錄頁
- 輸入之前配置的用戶名密碼,認證成功后會經過callback頁面,跳轉到客戶端首頁,並寫入cookie,sessionstorage