OAuth簡述:OAuth 2.0 的一個簡單解釋,理解OAuth 2.0
Angular引入OAuth 2.0:Angular-oauth2-oidc文檔
業務邏輯:客戶端請求登錄 -> 跳轉授權地址並登錄 -> 返回客戶端重定向地址 -> 返回客戶端地址
1.創建Angular 2項目
2.項目創建完成后安裝 angular-oauth2-oidc
npm i angular-oauth2-oidc --save
3.安裝完成后打開 AppModule 引入 OAuthModule
import { HttpClientModule } from '@angular/common/http'; import { OAuthModule } from 'angular-oauth2-oidc'; @NgModule({ imports: [ HttpClientModule, OAuthModule.forRoot() ], declarations: [ AppComponent, ], bootstrap: [ AppComponent ] }) export class AppModule { }
4.建立 OAuthConfig 簡單配置文件(更多配置請鏈接至Angular-oauth2-oidc文檔)
(1)issuer:后端授權地址
(2)redirectUrl:授權后返回客戶端的地址
(3)logoutUrl:用戶退出地址
(4)clientId:后端設置的客戶端ID
(5)scope:需要授權的權限
(6)sessionChecksEnabled:session檢查
(7)requireHttps:是否https
(8)silentRefreshRedirectUri:token到期刷新
import { AuthConfig } from 'angular-oauth2-oidc'; export const authConfig: AuthConfig = { // Url of the Identity Provider issuer: 'https://steyer-identity-server.azurewebsites.net/identity', // URL of the SPA to redirect the user to after login redirectUri: 'http://127.0.0.1:3000/callback', // The logout url logoutUrl: 'http://127.0.0.1:3000/index', // The SPA's id. The SPA is registered with this id at the auth-server clientId: 'spa-demo', // set the scope for the permissions the client should request // The first three are defined by OIDC. The 4th is a usecase-specific one scope: 'openid profile email voucher', /** * If true, the lib will try to check whether the user * is still logged in on a regular basis as described * in http://openid.net/specs/openid-connect-session-1_0.html#ChangeNotification */ sessionChecksEnabled: false, /** * Defines whether https is required. * The default value is remoteOnly which only allows * http for localhost, while every other domains need * to be used with https. */ requireHttps: false, // The redirect uri used when doing silent refresh silentRefreshRedirectUri: 'http://127.0.0.1:3000/assets/html/silent-refresh.html' }
5.建立 AppService 請求OAuth,並引入 OAuthConfig 配置文件
import { Injectable } from '@angular/core'; import { OAuthService } from 'angular-oauth2-oidc'; import { JwksValidationHandler } from 'angular-oauth2-oidc'; import { OAuthConfig } from './OAuthConfig'; @Injectable({ providedIn: 'root' }) export class AppService { constructor( private oauthSrv: OAuthService, ) { } public oauthConfig() { this.oauthSrv.configure(OAuthConfig.authConfig); this.oauthSrv.setStorage(localStorage); this.oauthSrv.tokenValidationHandler = new JwksValidationHandler(); this.oauthSrv.loadDiscoveryDocumentAndTryLogin({ onTokenReceived: url => { window.parent.location.href = url.state; } }); this.oauthSrv.setupAutomaticSilentRefresh(); } public identityValid() { if (this.oauthSrv.hasValidAccessToken()) { return true; } this.login(); return false; } public login() { const href = window.location.href; this.oauthSrv.initLoginFlow(href); } public logOut() { this.oauthSrv.logOut(); } }
6.在 AppComponent 中調用 AppService 的 oauthConfig 方法
import { Component } from '@angular/core'; import { AppService } from './service/app.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { constructor( private appSrv: AppService ) { this.appSrv.oauthConfig(); } }
7.創建 login 組件並引入 AppService 及調用登錄
async login() { await this.appSrv.login(); }
8.創建 project 組件並引入 AppService 調用驗證登錄
ngAfterViewInit(): void { this.init(); } async init() { await this.appSrv.identityValid(); }
9.創建 callback 組件,僅作為后端授權成功后的重定向地址
10.token的自動刷新,在 assets 中創建 silent-refresh.html 單頁面(參考)
<html> <body> <script> parent.postMessage(location.hash, location.origin); console.info('token has refreshed'); </script> </body> </html>