cognito
在本文中,我们将研究使用OAuth协议通过Amazon Cognito对单页应用程序(使用Vue.js构建)进行身份验证。 在上一篇文章中,我们将服务器端应用程序与Amazon Cognito集成在一起。
搭建单页应用程序
我们将使用vue-cli创建一个空的Vuejs应用程序。 可以按照此处的说明安装Vue CLI。
让我们通过发出以下命令来创建一个名为aws-cognito-spa-demo
的空应用程序:
vue create aws-cognito-spa-demo
系统将提示您选择插件
![亚马逊Cognito](https://i-blog.csdnimg.cn/blog_migrate/ff01eb1097ce96a1d2a17d4a598f2266.png)
创建应用程序后,您可以导航到该目录并发出命令以运行该应用程序
cd aws-cognito-spa-demo npm instal npm run serve
您将在http:// localhost:8080运行该应用程序
安装其他依赖项
我们将安装将用于该应用程序的必需节点软件包:
npm install --save amazon-cognito-auth-js npm install --save amazon-cognito-identity-js npm install --save vue-router npm install --save axios
在Amazon Cognito中创建新的App Client
我们将通过Amazon Cognito控制台创建一个名为test-spa-client
的新App客户test-spa-client
,如下所示:
![亚马逊Cognito](https://i-blog.csdnimg.cn/blog_migrate/d08c2fa17b43c8e11622ac775cdce31a.png)
通过提供回调URL,注销URL,允许的OAUth流和OAuth范围的值,导航到“应用程序客户端设置”来更新创建的客户端的设置:
![亚马逊Cognito](https://i-blog.csdnimg.cn/blog_migrate/d9e4a4eaa699c588fac4d9adf4a729bb.png)
我们使用隐式授予作为SPA应用程序的OAuth流。
创建环境变量
我们将与Amazon Cognito相关的设置存储在属性文件中,Vue CLI将在应用程序运行时使其在环境变量中可用。 在此处可以找到有关在Vue JS应用程序中定义环境变量的更多信息。
我们将在
文件中存储通用的应用程序设置,例如cognito重定向URI,注销URI,在.env
存储一些本地设置。 .env。*。local和.env.local文件从git中被忽略。 因此,您不必将本地设置提交到版本控制。 .env
# In .env VUE_APP_COGNITO_REDIRECT_URI=http: //localhost:8080/login/oauth2/code/cognito VUE_APP_COGNITO_REDIRECT_URI_SIGNOUT=http: //localhost:8080/logout VUE_APP_APP_URL=http: //localhost:8080
然后是.env.local中的以下内容:
VUE_APP_COGNITO_USERPOOL_ID=<cognito userpool id> VUE_APP_COGNITO_APP_DOMAIN=<cognito app domain> VUE_APP_COGNITO_CLIENT_ID=<app client id>
创建用户信息存储
我们将使用全局JSON对象存储已登录的用户信息。 这是使用Vuex的另一种方法。 让我们在src/app/user-info-store.js
创建JSON对象:
var state = {
cognitoInfo: {},
loggedIn: false ,
loadingState: true ,
errorLoadingState: false } function setLoggedIn(newValue) {
state.loggedIn = newValue; } function setLoggedOut() {
state.loggedIn = false ;
state.cognitoInfo = {}; } function setCognitoInfo(newValue){
state.cognitoInfo = newValue; } export default {
state: state,
setLoggedIn: setLoggedIn,
setLoggedOut: setLoggedOut,
setCognitoInfo: setCognitoInfo }
Amazon Cognito API的包装
让我们为Amazon Cognito API创建包装器src/app/auth.js
,这将简化诸如构建CognitoAuth
对象,登录和注销的操作:
/* eslint-disable */ {CognitoAuth, StorageHelper} from 'amazon-cognito-auth-js' import {CognitoAuth, StorageHelper} from ; IndexRouter from '../router/index' import IndexRouter from ; UserInfoStore from './user-info-store' import UserInfoStore from ; UserInfoApi from './user-info-api' import UserInfoApi from ; const CLIENT_ID = process.env.VUE_APP_COGNITO_CLIENT_ID; const APP_DOMAIN = process.env.VUE_APP_COGNITO_APP_DOMAIN; const REDIRECT_URI = process.env.VUE_APP_COGNITO_REDIRECT_URI; const USERPOOL_ID = process.env.VUE_APP_COGNITO_USERPOOL_ID; const REDIRECT_URI_SIGNOUT = process.env.VUE_APP_COGNITO_REDIRECT_URI_SIGNOUT; const APP_URL = process.env.VUE_APP_APP_URL; var authData = {
ClientId : CLIENT_ID, // Your client id here
AppWebDomain : APP_DOMAIN,
TokenScopesArray : [ 'openid' , 'email' ],
RedirectUriSignIn : REDIRECT_URI,
RedirectUriSignOut : REDIRECT_URI_SIGNOUT,
UserPoolId : USERPOOL_ID, } var auth = new CognitoAuth(authData); auth.userhandler = {
onSuccess: function(result) {
console.log( "On Success result" , result);
UserInfoStore.setLoggedIn( true );
UserInfoApi.getUserInfo().then(response => {
IndexRouter.push( '/' );
});
},
onFailure: function(err) {
UserInfoStore.setLoggedOut();
IndexRouter.go({ path: '/error' , query: { message: 'Login failed due to ' + err } }); 'Login failed due to ' + err } });
} }; function getUserInfoStorageKey(){
var keyPrefix = 'CognitoIdentityServiceProvider.' + auth.getClientId();
var tokenUserName = auth.signInUserSession.getAccessToken().getUsername();
var userInfoKey = keyPrefix + '.' + tokenUserName + '.userInfo' ;
return userInfoKey; } var storageHelper = new StorageHelper(); var storage = storageHelper.getStorage(); export default {
auth: auth,
login(){
auth.getSession();
},
logout(){
if (auth.isUserSignedIn()) {
var userInfoKey = this .getUserInfoStorageKey();
auth.signOut();
storage.removeItem(userInfoKey);
}
},
getUserInfoStorageKey, }
从Amazon Cognito获取用户信息
身份验证之后,我们可以使用访问令牌来获取有关登录用户的信息。为此,我们必须向端点发出GET请求: https://<app domain>/oauth2/userInfo
。 我们在src/app/user-info.js
创建了一个实用程序方法getUserInfo()
,如下所示:
axios from 'axios' import axios from ; auth from './auth' import auth from ; export default {
getUserInfo(){
var jwtToken = auth.auth.getSignInUserSession().getAccessToken().jwtToken;
const USERINFO_URL = ' https:// ' +auth.auth.getAppWebDomain() + '/oauth2/userInfo' ;
var requestData = {
headers: {
'Authorization' : 'Bearer ' + jwtToken
}
}
return axios.get(USERINFO_URL, requestData).then(response => {
return response.data;
});
} }
上面部分编写的Cognito包装器已使用此API。
创建Vue组件
让我们为以下目的创建一些Vue组件:
- 显示已登录的用户信息
- 显示注销成功
- 错误处理组件
我们将使用Vue路由器将URL路径映射到Vue组件。 组件定义如下所示:
Home
组件
<template>
<div class = "row" >
<div class = "col" >
<h3>Welcome, </h3>
<div class = "alert alert-info" >
{{userInfo}}
</div>
<router-link to= "/logout" >
Logout
</router-link>
</div>
</div> </template> <script> UserInfoStore from '../app/user-info-store' import UserInfoStore from ; export default {
name: 'Home' ,
data: function() {
return {
userInfo: UserInfoStore.state.cognitoInfo
}
} } </script> <style> </style>
LogoutSuccess
组件:
<template> <div class = "row" >
<div class = "col" >
<h2>Logged Out successfully</h2>
<router-link to= "/login" >Login</router-link>
</div> </div> </template> <script> export default {
mounted: function(){
} } </script>
错误组件:
<template>
<div class = "alert alert-danger" >
{{message}}
</div> </template> <script> export default {
data: function(){
return {
message: ""
}
},
mounted(){
this .message = this .$route.query.message;
} } </script>
设置路由器
如前一节所述,我们将使用Vue Router将URL路径映射到Vue组件。 我们将在router/index.js
设置路由器配置,如下所示:
/* eslint-disable */ Vue from 'vue' import Vue from Router from 'vue-router' import Router from Home from '@/components/Home' import Home from auth from '../app/auth' import auth from ; LogoutSuccess from '@/components/LogoutSuccess' import LogoutSuccess from ; UserInfoStore from '../app/user-info-store' import UserInfoStore from ; UserInfoApi from '../app/user-info-api' import UserInfoApi from ; ErrorComponent from '@/components/Error' import ErrorComponent from ; Vue.use(Router) function requireAuth(to, from, next) {
if (!auth.auth.isUserSignedIn()) {
UserInfoStore.setLoggedIn( false );
next({
path: '/login' ,
query: { redirect: to.fullPath }
});
} else {
UserInfoApi.getUserInfo().then(response => {
UserInfoStore.setLoggedIn( true );
UserInfoStore.setCognitoInfo(response);
next();
});
} } export default new Router({
mode: 'history' ,
base: '/' ,
routes: [
{
path: '/' ,
name: 'Home' ,
component: Home,
beforeEnter: requireAuth
},
{
path: '/login' , beforeEnter(to, from, next){
auth.auth.getSession();
}
},
{
path: '/login/oauth2/code/cognito' , beforeEnter(to, from, next){
var currUrl = window.location.href;
//console.log(currUrl);
auth.auth.parseCognitoWebResponse(currUrl);
//next();
}
},
{
path: '/logout' , component: LogoutSuccess, beforeEnter(to, from, next){
auth.logout();
next();
}
},
{
path: '/error' , component: ErrorComponent
}
] })
我们利用路由对象的beforeEnter
属性来添加呈现组件所需的所有先决条件。 然后在此属性中,检查用户是否使用我们创建的Cognito包装器登录。 因此,对于需要保护的路径,我们可以定义beforeEnter
属性。
创建的默认应用程序具有一个App.vue
组件,它将成为我们的根组件。 我们使用<router-view/>
标记表示此处HTML将基于路由器配置中路径解析到的组件。
因此,我们的App.vue
版本如下所示:
<template>
<div id= "app" >
<img alt= "Vue logo" src= "./assets/logo.png" >
<div class = "contents" >
<router-view/>
</div>
</div> </template> <script> export default {
name: 'app' } </script> <style> #app {
font-family: 'Avenir' , Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px; } </style>
然后,我们更新src/main.js
以引用包含路由器配置的目录,如下所示:
Vue from 'vue' import Vue from App from './App.vue' import App from router from './router' import router from Vue.config.productionTip = false new Vue({
render: h => h(App),
router }).$mount( '#app' )
运行应用程序
您可以通过发出以下命令来运行该应用程序: npm run serve
。 导航到localhost:8080将带您进入Cognito登录屏幕:
![亚马逊Cognito](https://i-blog.csdnimg.cn/blog_migrate/62597e79244d2272a8db299a7b5e6fd2.png)
输入您已经在用户池中注册的用户的用户名和密码,甚至可以注册一个新用户。 登录后,您将被重定向回Vue JS应用:
![亚马逊Cognito](https://i-blog.csdnimg.cn/blog_migrate/a230ef4e4cb35d69c8efefa9360764a4.png)
注销链接将注销用户。
完整的代码可以在Github仓库中找到 。
翻译自: https://www.javacodegeeks.com/2019/04/amazon-cognito-single-page-application-vue.html
cognito