auth.service.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import { Injectable } from '@angular/core';
  2. import { OAuthSuccessEvent } from '../oauth2-oidc/events';
  3. import { OAuthService } from '../oauth2-oidc/oauth-service';
  4. import { Platform } from '@ionic/angular';
  5. import { StorageService } from './storage.service';
  6. import { Router } from '@angular/router';
  7. import { InAppBrowser } from '@ionic-native/in-app-browser/ngx';
  8. import { ButtonService } from './button.service';
  9. @Injectable({
  10. providedIn: 'root',
  11. })
  12. export class AuthService {
  13. loginBackKey = 'passport-login-call-back';
  14. loginBackRoute = '/passport/login-call-back';
  15. loginRoute = '/user-profile';
  16. constructor(
  17. private oauthService: OAuthService,
  18. private platform: Platform,
  19. private stoage: StorageService,
  20. private router: Router,
  21. private iab: InAppBrowser,
  22. private btnService: ButtonService,
  23. ) {
  24. let serUrl = 'http://127.0.0.1:100';
  25. if (platform.is('hybrid')) {
  26. serUrl = 'http://192.168.137.1:100';
  27. }
  28. this.oauthService.configure({
  29. issuer: serUrl,
  30. // issuer: 'https://idsvr4.azurewebsites.net',
  31. // URL of the SPA to redirect the user to after login
  32. redirectUri: window.location.origin + this.loginBackRoute,
  33. // The SPA's id. The SPA is registerd with this id at the auth-server
  34. // clientId: 'server.code',
  35. clientId: 'SPA',
  36. postLogoutRedirectUri: window.location.origin + this.loginRoute,
  37. dummyClientSecret: 'secret',
  38. // Just needed if your auth server demands a secret. In general, this
  39. // is a sign that the auth server is not configured with SPAs in mind
  40. // and it might not enforce further best practices vital for security
  41. // such applications.
  42. // dummyClientSecret: 'secret',
  43. responseType: 'code',
  44. requireHttps: false,
  45. // set the scope for the permissions the client should request
  46. // The first four are defined by OIDC.
  47. // Important: Request offline_access to get a refresh token
  48. // The api scope is a usecase specific one
  49. scope: 'openid profile',
  50. showDebugInformation: true,
  51. });
  52. // this.load();
  53. }
  54. async load(): Promise<OAuthSuccessEvent> {
  55. const oAuthSuccessEvent = await this.oauthService.loadDiscoveryDocument();
  56. const isLogin = await this.oauthService.hasValidAccessToken();
  57. if (!isLogin) {
  58. await this.oauthService.tryLogin();
  59. }
  60. return oAuthSuccessEvent;
  61. }
  62. async login() {
  63. // 登录前先保存登录地址缓存
  64. await this.stoage.setItem(this.loginBackKey, this.router.url);
  65. // 登录前先跳转无需权限页面,比如登录等待界面
  66. this.router.navigateByUrl(this.loginRoute, { replaceUrl: true });
  67. if (this.platform.is('hybrid')) {
  68. await this.mobileLogin();
  69. } else {
  70. await this.webLogin();
  71. }
  72. }
  73. async webLogin() {
  74. this.oauthService.initLoginFlow();
  75. }
  76. async mobileLogin() {
  77. const loginUrl = await this.oauthService.getLoginUrl();
  78. const browser = this.iab.create(loginUrl, '_blank', {
  79. location: 'no',
  80. zoom: 'no',
  81. });
  82. const listener = browser.on('loadstart').subscribe((event) => {
  83. if (event.url.indexOf(this.loginBackRoute) > -1) {
  84. const customHashFragment = event.url.split(this.loginBackRoute)[1];
  85. this.oauthService.tryLoginCodeFlow({ customHashFragment }).then(() => {
  86. // 跳转登录成功页面
  87. this.router.navigateByUrl(this.loginBackRoute, { replaceUrl: true });
  88. });
  89. listener.unsubscribe();
  90. browser.close();
  91. }
  92. });
  93. }
  94. async isLogined() {
  95. const isLogin = await this.oauthService.hasValidAccessToken();
  96. // return isLogin;
  97. if (!isLogin) {
  98. this.login();
  99. }
  100. return isLogin;
  101. }
  102. async token(): Promise<string> {
  103. return this.oauthService.getIdToken();
  104. }
  105. async loginOut() {
  106. if (this.platform.is('hybrid')) {
  107. const loginUrl = await this.oauthService.getLogOutUrl();
  108. const browser = this.iab.create(loginUrl, '_blank', {
  109. location: 'no',
  110. zoom: 'no',
  111. });
  112. const listener = browser.on('loadstart').subscribe((event) => {
  113. if (event.url.indexOf(this.loginRoute) > -1) {
  114. listener.unsubscribe();
  115. browser.close();
  116. this.btnService.exit();
  117. }
  118. });
  119. } else {
  120. await this.oauthService.logOut();
  121. }
  122. }
  123. }