import { Injectable } from '@angular/core'; import { OAuthSuccessEvent } from '../oauth2-oidc/events'; import { OAuthService } from '../oauth2-oidc/oauth-service'; import { Platform } from '@ionic/angular'; import { StorageService } from './storage.service'; import { Router } from '@angular/router'; import { InAppBrowser } from '@ionic-native/in-app-browser/ngx'; import { ButtonService } from './button.service'; @Injectable({ providedIn: 'root', }) export class AuthService { loginBackKey = 'passport-login-call-back'; loginBackRoute = '/passport/login-call-back'; loginRoute = '/user-profile'; constructor( private oauthService: OAuthService, private platform: Platform, private stoage: StorageService, private router: Router, private iab: InAppBrowser, private btnService: ButtonService, ) { let serUrl = 'http://127.0.0.1:100'; if (platform.is('hybrid')) { serUrl = 'http://192.168.137.1:100'; } this.oauthService.configure({ issuer: serUrl, // issuer: 'https://idsvr4.azurewebsites.net', // URL of the SPA to redirect the user to after login redirectUri: window.location.origin + this.loginBackRoute, // The SPA's id. The SPA is registerd with this id at the auth-server // clientId: 'server.code', clientId: 'SPA', postLogoutRedirectUri: window.location.origin + this.loginRoute, dummyClientSecret: 'secret', // Just needed if your auth server demands a secret. In general, this // is a sign that the auth server is not configured with SPAs in mind // and it might not enforce further best practices vital for security // such applications. // dummyClientSecret: 'secret', responseType: 'code', requireHttps: false, // set the scope for the permissions the client should request // The first four are defined by OIDC. // Important: Request offline_access to get a refresh token // The api scope is a usecase specific one scope: 'openid profile', showDebugInformation: true, }); // this.load(); } async load(): Promise { const oAuthSuccessEvent = await this.oauthService.loadDiscoveryDocument(); const isLogin = await this.oauthService.hasValidAccessToken(); if (!isLogin) { await this.oauthService.tryLogin(); } return oAuthSuccessEvent; } async login() { // 登录前先保存登录地址缓存 await this.stoage.setItem(this.loginBackKey, this.router.url); // 登录前先跳转无需权限页面,比如登录等待界面 this.router.navigateByUrl(this.loginRoute, { replaceUrl: true }); if (this.platform.is('hybrid')) { await this.mobileLogin(); } else { await this.webLogin(); } } async webLogin() { this.oauthService.initLoginFlow(); } async mobileLogin() { const loginUrl = await this.oauthService.getLoginUrl(); const browser = this.iab.create(loginUrl, '_blank', { location: 'no', zoom: 'no', }); const listener = browser.on('loadstart').subscribe((event) => { if (event.url.indexOf(this.loginBackRoute) > -1) { const customHashFragment = event.url.split(this.loginBackRoute)[1]; this.oauthService.tryLoginCodeFlow({ customHashFragment }).then(() => { // 跳转登录成功页面 this.router.navigateByUrl(this.loginBackRoute, { replaceUrl: true }); }); listener.unsubscribe(); browser.close(); } }); } async isLogined() { const isLogin = await this.oauthService.hasValidAccessToken(); // return isLogin; if (!isLogin) { this.login(); } return isLogin; } async token(): Promise { return this.oauthService.getIdToken(); } async loginOut() { if (this.platform.is('hybrid')) { const loginUrl = await this.oauthService.getLogOutUrl(); const browser = this.iab.create(loginUrl, '_blank', { location: 'no', zoom: 'no', }); const listener = browser.on('loadstart').subscribe((event) => { if (event.url.indexOf(this.loginRoute) > -1) { listener.unsubscribe(); browser.close(); this.btnService.exit(); } }); } else { await this.oauthService.logOut(); } } }