企业网站建设招标,flashfxp 网站,扁平化色彩网站,vue vs wordpressangular 接入 IdentityServer4Intro最近把活动室预约的项目做了一个升级#xff0c;预约活动室需要登录才能预约#xff0c;并用 IdentityServer4 做了一个统一的登录注册中心#xff0c;这样以后就可以把其他的需要用户操作的应用统一到 IdentityServer 这里#xff0c;这… angular 接入 IdentityServer4Intro最近把活动室预约的项目做了一个升级预约活动室需要登录才能预约并用 IdentityServer4 做了一个统一的登录注册中心这样以后就可以把其他的需要用户操作的应用统一到 IdentityServer 这里这样就不需要在每个应用里都做一套用户的机制接入 IdentityServer 就可以了。目前活动室预约的服务器端和基于 angular 的客户端已经完成了 IdentityServer 的接入并增加了用户的相关的一些功能比如用户可以查看自己的预约记录并且可以取消自己未开始的预约还有一个小程序版的客户端暂时还未完成接入所以小程序版目前暂时是不能够预约的为什么要写这篇文章目前在网上看到很多都是基于 implicit 模式接入 IdentityServer这样实现起来很简单但是现在 OAuth 已经不推荐这样做了OAuth 推荐使用 code 模式来代替 implicitimplicit 模式会有一些安全风险implicit 模式会将 accessToken 直接返回到客户端而 code 模式只是会返回一个 codeaccessToken 和 code 的分离的两步implicit 模式很有可能会将 token 泄露出去详细可以参考 StackOverflow 上的这个问答https://stackoverflow.com/questions/13387698/why-is-there-an-authorization-code-flow-in-oauth2-when-implicit-flow-works除此之外还有一个小原因大多是直接基于 oidc-client 的 一个 npm 包来实现的我是用了一个针对 angular 封装的一个库 angular-oauth2-oidc如果你在用 angular 建议你可以尝试一下针对 angular 做了一些封装和优化对 angular 更友好一些准备接入吧API 配置预约系统的 API 和网站管理系统是在一起的针对需要登录才能访问的 API 单独设置了的 policy 访问services.AddAuthentication().AddIdentityServerAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme, options {options.Authority Configuration[Authorization:Authority];options.RequireHttpsMetadata false;options.NameClaimType name;options.RoleClaimType role;});services.AddAuthorization(options
{options.AddPolicy(ReservationApi, builder builder.AddAuthenticationSchemes(IdentityServerAuthenticationDefaults.AuthenticationScheme).RequireAuthenticatedUser().RequireScope(ReservationApi));
});
需要授权才能访问的接口设置 Authorize 并指定 Policy 为 ReservationApi[Authorize(Policy ReservationApi)]
[HttpPost]
public async TaskIActionResult MakeReservation([FromBody] ReservationViewModel model)
IdentityServer Client 配置首先我们需要在 IdentityServer 这边添加一个客户端因为我们要使用 code 模式所以授权类型需要配置 authorization-code 模式不使用 implicit 模式允许的作用域scope 是客户端允许访问的 api 资源和用户的信息资源openid 必选profile 是默认的用户基本信息的集合根据自己客户端的需要进行配置ReservationApi 是访问 API 需要的 scope其他的 scope 根据客户端需要进行配置angular 客户端配置安装 angular-oauth2-oidc npm 包我现在使用的是 9.2.0 版本添加 oidc 配置export const authCodeFlowConfig: AuthConfig {issuer: https://id.weihanli.xyz,// URL of the SPA to redirect the user to after loginredirectUri: window.location.origin /account/callback,clientId: reservation-angular-client,dummyClientSecret: f6f1f917-0899-ef36-63c8-84728f411e7c,responseType: code,scope: openid profile ReservationApi offline_access,useSilentRefresh: false,showDebugInformation: true,sessionChecksEnabled: true,timeoutFactor: 0.01,// disablePKCI: true,clearHashAfterLogin: false
};
在 app.module 引入 oauth 配置 imports: [BrowserModule,AppRoutingModule,AppMaterialModule,HttpClientModule,FormsModule,ReactiveFormsModule,BrowserAnimationsModule,OAuthModule.forRoot({resourceServer: {allowedUrls: [https://reservation.weihanli.xyz/api],sendAccessToken: true}})]
OAuthModule 里 resourceServer 中的 allowedUrls 是配置的资源的地址访问的资源符合这个地址时就会自动发送 accessToken这样就不需要自己实现一个 interceptor 来实现自动在请求头中设置 accessToken 了在 AppComponment 的构造器中初始化 oauth 配置并加载 ids 的发现文档export class AppComponent {constructor(private oauth: OAuthService) {this.oauth.configure(authConfig.authCodeFlowConfig);this.oauth.loadDiscoveryDocument();}// ...
}
添加一个 AuthGuard路由守卫需要登录才能访问的页面自动跳转到 /account/login 自动登录AuthGuard:import { Injectable } from angular/core;
import { CanActivate, Router } from angular/router;
import { OAuthService } from angular-oauth2-oidc;Injectable({providedIn: root
})
export class AuthGuard implements CanActivate {constructor(private router: Router, private oauthService: OAuthService) {}canActivate() {if (this.oauthService.hasValidAccessToken()) {return true;} else {this.router.navigate([/account/login]);return false;}}
}路由配置import { NgModule } from angular/core;
import { Routes, RouterModule } from angular/router;
import { ReservationListComponent } from ./reservation/reservation-list/reservation-list.component;
import { NoticeListComponent } from ./notice/notice-list/notice-list.component;
import { NoticeDetailComponent } from ./notice/notice-detail/notice-detail.component;
import { AboutComponent } from ./about/about.component;
import { NewReservationComponent } from ./reservation/new-reservation/new-reservation.component;
import { LoginComponent } from ./account/login/login.component;
import { AuthGuard } from ./shared/auth.guard;
import { AuthCallbackComponent } from ./account/auth-callback/auth-callback.component;
import { MyReservationComponent } from ./account/my-reservation/my-reservation.component;const routes: Routes [{ path: , component: ReservationListComponent },{ path: reservations/new, component:NewReservationComponent, canActivate: [AuthGuard] },{ path: reservations, component: ReservationListComponent },{ path: notice, component: NoticeListComponent },{ path: notice/:noticePath, component: NoticeDetailComponent },{ path: about, component: AboutComponent },{ path: account/login, component: LoginComponent },{ path: account/callback, component: AuthCallbackComponent },{ path: account/reservations, component: MyReservationComponent, canActivate: [AuthGuard] },{ path: **, redirectTo: /}
];NgModule({imports: [RouterModule.forRoot(routes)],exports: [RouterModule]
})
export class AppRoutingModule { }
AccountLogin 会将用户引导到 ids 进行登录登录之后会跳转到配置的重定向 url我配置的是 account/callbackimport { Component, OnInit } from angular/core;
import { OAuthService } from angular-oauth2-oidc;Component({selector: app-login,templateUrl: ./login.component.html,styleUrls: [./login.component.less]
})
export class LoginComponent implements OnInit {constructor(private oauthService: OAuthService) {}ngOnInit(): void {// 登录this.oauthService.initLoginFlow();}}
Auth-Callbackimport { Component, OnInit } from angular/core;
import { OAuthService } from angular-oauth2-oidc;
import { Router } from angular/router;Component({selector: app-auth-callback,templateUrl: ./auth-callback.component.html,styleUrls: [./auth-callback.component.less]
})
export class AuthCallbackComponent implements OnInit {constructor(private oauthService: OAuthService, private router:Router) {}ngOnInit(): void {this.oauthService.loadDiscoveryDocumentAndTryLogin().then(_ {this.oauthService.loadUserProfile().then(x{this.router.navigate([/reservations/new]);});});}}
More当前实现还不太完善重定向现在始终是跳转到的新预约的页面应当在跳转登录之前记录一下当前的地址保存在 storage 中在 auth-callback 里登录成功之后跳转到 storage 中之前的地址更多信息可以参考 angular 源码 https://github.com/OpenReservation/angular-client API 源码https://github.com/OpenReservation/ReservationServerReferencehttps://sunnycoding.cn/2020/03/14/angular-spa-auth-with-ocelot-and-ids4-part3/#i-2https://github.com/OpenReservation/angular-clienthttps://github.com/manfredsteyer/angular-oauth2-oidc/https://github.com/OpenReservation/ReservationServer