文章目录

  • UserAuthModule
    • Authentication Flow
    • AuthService
    • Storing Tokens and User Identifiers
    • 用户认证的典型流程和包含步骤
    • Access Tokens in API Calls and Error Recovery
    • Persisting Authentication Data in the Browser Storage
    • ASM
    • Configuring Authorization Code Flow or Implicit Flow
    • Commerce Cloud的一个限制
  • Specifies if new refresh token should be created during refreshing an Access Token
  • reuseRefreshToken = true - old refresh token will be returned, refresh token can be used more than one time
  • reuseRefreshToken = false - new refresh token will be created
  • Specifies if new refresh token should be created during refreshing an Access Token
  • reuseRefreshToken = true - old refresh token will be returned, refresh token can be used more than one time
  • reuseRefreshToken = false - new refresh token will be created
  • Specifies if new refresh token should be created during refreshing an Access Token
  • reuseRefreshToken = true - old refresh token will be returned, refresh token can be used more than one time
  • reuseRefreshToken = false - new refresh token will be created
  • Commerce Cloud Authentication

  • SAP Spartacus 用户认证的实现

  1. Client Authentication and User Authentication
    From the beginning, Spartacus has included both client authentication and user authentication. Although this is not typical for web applications, it is necessary for Spartacus to work with the OCC API.

SAP Spartacus 支持 client 认证和 user 认证,为了配合 Commerce Cloud OCC API.

  1. There are a number of endpoints that work on behalf of logged-out users, such as registering, resetting a password, placing an order as a guest, and verifying an address.

OCC API 有不少 endpoints是针对未登录用户调用的,比如用户注册,密码重置,以guest方式下单等等。

  1. These endpoints require an access token to be sent with the request, and this access token needs to be retrieved by following the Client Credentials Flow that is defined by the OAuth specification. This is the client authentication.

这些匿名用户消费的OCC API,也需要提供Access Token才能访问。Access Token通过OAuth协议里定义的名叫Client Credentials Flow这一认证流来获取。这个过程称为Client Authentication.

  1. Meanwhile, user authentication is used for requests that are sent on behalf of specific user resources. For example, if you want to update your profile, you need to be logged in. When you log in, the server confirms your credentials and returns an access token to the application. This token is then used for all requests on your account, such as updating your profile, making cart modifications, and checking out.

而User Authentication,则是调用代表某一登录用户,向Commerce Cloud后台发起 API 调用之前必须完成的流程,比如更新用户的profile,此时该用户必须首先登录。用户登录后,Commerce Cloud 确认用户credentials之后,返回Access Token,接下来该登录用户调用的所有OCC API,都使用该Access Token来完成。

  1. Prior to Spartacus 3.0, the code for both client authentication and user authentication was in the AuthModule, which included interceptors, services, and facade methods all mixed together. In Spartacus 3.0, the AuthModule still contains client and user authentication, but this is now the result of importing two modules, the UserAuthModule and the ClientAuthModule. Each module is responsible for one type of authentication.

在Spartacus 3.0之前,client和user认证都实现在AuthModule里,在3.0进行了一些重构,AuthModule导入了两个Module, 分别进行这两种认证:

  • UserAuthModule
  • ClientAuthModule

UserAuthModule

源代码位置:spartacus\projects\core\src\auth\user-auth\user-auth.module.ts

https://github.com/SAP/spartacus/tree/develop/projects/core/src/auth/user-auth

UserAuthModule完成的5大任务

  • performing authentication flow: 执行认证流
  • storing tokens and user identifiers:存储token
  • adding access tokens for user calls:给用户发起的HTTP请求添加Access Token
  • recovering from API auth errors (for example, refreshing tokens when access tokens expire):API出现认证错误时的自动恢复机制,比如当Access Token过期时,自动刷新token
  • persisting the tokens in browser storage - 将token存储在浏览器storage里

Authentication Flow

Spartacus 3.0 使用开源的angular-oauth2-oidc来完成用户认证。

下图高亮区域包含了用户认证过程中使用到的服务。

AuthService

AuthService是一个service facade,消费者可以调用它提供的下列两个方法,触发认证流程。

  • loginWithCredentials:for the Resource Owner Password Flow
  • loginWithRedirect:for the Implicit Flow or the Authorization Code Flow

The login method then interacts with the angular-oauth2-oidc library. However, this interaction always goes through the OAuthLibWrapperService, which is a layer for isolating external libraries from Spartacus code.

login方法通过OAuthLibWrapperService,调用angular-oauth2-oidc这个开源库。OAuthLibWrapperService作为一个中间层,将Spartacus 代码同第三方代码隔离开。

The OAuthLibWrapperService class is also responsible for configuring the library. It uses the AuthConfigService to access the AuthConfig configuration provided in the application.

OauthLibWrapperService还包含了第三方库的配置信息,使用AuthConfigService来访问AuthConfig配置信息。

Storing Tokens and User Identifiers

After authentication, the tokens received from the library methods need to be stored somewhere.

用户认证完成之后,服务器颁发的token通过开源库文件接收,然后需要存储在某处。

Previously, these tokens were kept in NgRx Store, but in Spartacus 3.0, there are dedicated services to keep the data.

在3.0之前,这些token存储在NgRx store里,到了3.0, 有专门的服务用于存储数据。

The library requires a storage mechanism with an API similar to localStorage or sessionStorage, and that was the main reason to switch from NgRx to services with a stream for keeping the data.

因为我们使用的开源angular-oauth2-oidc,需要相应的存储机制采取类似localStorage或者SessionStorage的工作方式来配合,因此在3.0里,我们从NgRx切换成了支持Stream的自定义服务。

这些服务高亮如下:

For authentication, it is normally sufficient to store only tokens and their metadata (such as expiration time and scope).

对于认证机制来说,仅仅存储token及其元数据即可,比如token的过期时间和scope.

However, with OCC, there is also the tightly-coupled user ID that needs to be set after login or logout, as well as being required for user emulation when working with the Assisted Service Module (ASM).

然而由于Commerce Cloud后台实现的特殊性,在用户登录之后,需要设置一个紧耦合的user ID,并且在ASM模块的user emulation场景下,也需要这个user ID.

Prior to Spartacus 3.0, the user ID was kept in the same place as the tokens in NgRx, and because of that previous association, the user ID remains in the UserAuthModule.

User ID 存储于UserAuthModule.

However, the tokens have now been separated from the user identifier in this module. Tokens and their metadata are now stored with the AuthStorageService, while user IDs have their own, dedicated UserIdService.

Token现在存储于AuthStorageService里, 而User ID 存储于 UserIdService里。

用户认证的典型流程和包含步骤

  1. a user invokes login - 用户触发登录动作
  2. the authentication library perform the OAuth flow and receives tokens - 开源库执行OAuth认证流,接收到token
  3. the authentication library directly sets the tokens in the through the setItem and removeItem methods - 开源OAuth库,调用AuthStorageServiced的setItem方法,将token存储:

  1. the AuthService is informed about the successful login - AuthService收到登录成功的通知;
  2. the AuthService sets the user ID in the UserIdService for the logged-in user - AuthService在UserIdService里设置用户ID

The UserIdService is part of a facade, because almost all services that interact with the OCC API require it. Previously, the user ID was exposed in the AuthService.getOccUserId. As a result, in Spartacus 3.0 it has been kept in the same facade, but in a different service and in a different method.

UserIDService是一个facade.

Access Tokens in API Calls and Error Recovery

After logging in a user, and storing their access token and user ID, it is then possible to request some of the user’s resources. To do so, it is necessary to pass an access token as a header in the request. In Spartacus, this is achieved with HTTP interceptors, as shown in the following diagram.

用户成功登录后,接下来发起的所有OCC API调用,都需要附上Access Token. 这个行为通过HTTP Interceptors完成。

The AuthInterceptor recognizes the request to the API based on the URL. If the request does not have the Authorization header, and does match the API path, the interceptor adds the header to the request. To make it easier to extend the interceptor, Spartacus has its own AuthHttpHeaderService helper service. In most cases, extending this one service should be enough.

应用开发人员无需进行任何操作,如果请求没有包含Authorization头部字段,并且路径能够匹配,那么interceptor会自动添加头部字段。Interceptor使用AuthHttpHeaderService作为Helper Service,可以被partners扩展。

Apart from injecting the token, this interceptor is also responsible for handling errors that are related to authorization. In such cases, it tries to recover first and retry the request, and if that is not possible, it completes the logout process and redirects the user to the login page. When a request fails because the access token has expired, the interceptor uses the refresh token (if it exists) to request a new access token, and then retries the failed request with the new token.

Interceptor的另一个作用,当请求报错时,interceptor首先尝试retry,如果还不能成功,会执行logout流程,将用户重定向到login页面去。当请求由于Access Token过期导致失败时,Interceptor会使用refresh token请求新的Access Token, 然后使用新得到的Access Token重发请求。

Persisting Authentication Data in the Browser Storage

After you log in, and your token has been stored and used for API calls, you refresh the page and suddenly you are no longer logged in. To avoid this problem, the AuthStatePersistenceService synchronizes the authentication data (such as tokens and user ID) in the browser storage, as shown in the following diagram.

AuthStatePersistenceService 负责将token,用户ID等认证后返回的信息,同步到浏览器存储介质里。

The AuthStatePersistenceService uses the StatePersistenceService to synchronize data to and from the browser storage. The user ID from the UserIdService, the tokens from the AuthStorageService, and the redirect URL from the AuthRedirectStorageService are all synchronized to the localStorage. Every time data changes, it is saved in the browser storage, and when the application starts, it is read from the storage into services.

  • UserID - 由UserIdService提供
  • token - AuthStorageService
  • redirectUrl - AuthRedirectStorageService

以上三种数据全部同步到LocalStorage里。这些数据发生变化时,最新的数据都会存储到浏览器storage里,当应用启动时,直接从浏览器介质里加载到应用。

ASM

Since version 1.3, Spartacus supports the Assisted Service Module (ASM), which allows customer support agents to emulate users and help them accomplish their goals. This feature is tightly coupled with the AuthModule because agents need to log in with OAuth flow and make updates using the customer’s user ID.

从1.3版本开始,SAP Spartacus支持ASM模块,允许Customer support座席通过模拟用户的方式来帮助客户解决问题。ASM同AuthModule具有紧耦合关系,因为座席需要使用OAuth flow登录,然后使用客户的User ID进行操作。

Configuring Authorization Code Flow or Implicit Flow

Now the Spartacus uses the angular-oauth2-oidc library, it is possible to support the Authorization Code Flow and the Implicit Flow.

既然Spartacus使用angular-oauth2-oidc库,这意味着我们可以支持Authorization Code Flow 以及Implicit Flow.

These flows are very different from the Resource Owner Password Flow because the authentication part happens on the OAuth server login page rather than in Spartacus.

这两种flow同Resource Owner Password flow有很大区别,因此其认证过程发生在OAuth server的登录页面,而不是在Spartacus里。

When Spartacus redirects you to this page, you provide login and password information there, and if the credentials match, you are redirected back to the Spartacus application with the token (Implicit Flow) or code (Authorization Code Flow) as part of the URL.

当Spartacus将用户重定向到OAuth服务器的登录页面后,用户提供用户名和密码,如果认证通过,用户会被重定向回Spartacus,并且url的一部分,包含了token(Implicit Flow场景)或者Code(Authorization Code Flow).

Then Spartacus obtains the data from the URL and continues the login process (requests a token in the case of Authorization Code Flow, sets the user ID, dispatches the Login action, and redirects to the previously visited page).

Spartacus从url中获取了数据之后,就能继续login流程,比如在Authorization Code Flow里,设置User ID,分发Login action,重定向客户回之前曾经访问过的页面。

authentication: {OAuthLibConfig: {responseType: 'token', // 'code`代表for Authorization Code Flow ,而token代表Implicit Flow},
},

Apart from this configuration, you may need to update a few details for your OAuth client in Backoffice (such as allowing Implicit Flow or Authorization Code Flow, and setting the redirect URL of the application).

在Backoffice里配置OAuth client的明细,比如允许Implicit flow或者Authorization code flow,设置redirect url等等。

Once these settings are in place, Spartacus will use the defined flow out of the box.

The login route is configured in a way that detects the OAuth flow based on the configuration (LoginGuard and LoginRouteModule). When it detects a flow other than the Resource Owner Password Flow, Spartacus saves the previous URL (to redirect to after login), and redirects you to the OAuth server login page.

Commerce Cloud的一个限制

The default OAuth server that is provided with SAP Commerce Cloud does not have great support for the Authorization Code Flow and the Implicit Flow (there is no way to log out a user from an external application, and no way to customize the login page).

SAP Commerce Cloud使用的默认OAuth服务器,没法完善地支持Authorization Code Flow和Implicit flow,比如无法从外部应用登出一个用户,没法自定义login页面等等。

So for now it is expected that everyone using this OAuth server will continue to work with the Resource Owner Password Flow.

因此,使用SAP Commerce Cloud默认的OAuth服务器,意味着我们选用Resource Owner Password flow.

Resource Owner Password Credentials 授权和 Client Credentials 授权, 简称 Password 方式和 Client 方式,都只适用于应用是受信任的场景。一个典型的例子是同一个企业内部的不同产品要使用本企业的 OAuth 2.0 体系。在有些情况下,产品希望能够定制化授权页面。由于是同个企业,不需要向用户展示“xxx将获取以下权限”等字样并询问用户的授权意向,而只需进行用户的身份认证即可。这个时候,由具体的产品团队开发定制化的授权界面,接收用户输入账号密码,并直接传递给鉴权服务器进行授权即可。如果信任关系再进一步,或者调用者是一个后端的模块,没有用户界面的时候,可以使用 Client 方式。

However, if you use a different OAuth server (such as Auth0), you can switch to either of these flows.

当然,如果不用Commerce Cloud默认的OAuth认证服务器,就可以选择切换到其他OAuth 认证 flow去。

oauthauthorizationserver.tokenServices.reuseRefreshToken=false”setting that to true should in theory only help in the case where:

  • you are logged in on 1 device

  • a bit later you log in on another device

  • your session expires on one first device

  • if the property is true, and it’s not 12 hours since login to 2nd device, you can still continue browsing. If false, you get logged out there too

Specifies if new refresh token should be created during refreshing an Access Token

reuseRefreshToken = true - old refresh token will be returned, refresh token can be used more than one time

reuseRefreshToken = false - new refresh token will be created

oauthauthorizationserver.tokenServices.reuseRefreshToken=false

Specifies if new refresh token should be created during refreshing an Access Token

reuseRefreshToken = true - old refresh token will be returned, refresh token can be used more than one time

reuseRefreshToken = false - new refresh token will be created

oauthauthorizationserver.tokenServices.reuseRefreshToken=false

Specifies if new refresh token should be created during refreshing an Access Token

reuseRefreshToken = true - old refresh token will be returned, refresh token can be used more than one time

reuseRefreshToken = false - new refresh token will be created

oauthauthorizationserver.tokenServices.reuseRefreshToken=false

更多Jerry的原创文章,尽在:“汪子熙”:

SAP Spartacus 用户认证的实现相关推荐

  1. SAP Spartacus 用户请求中的 current id 是从哪里来的

    从 SAP Spartacus 成功登录之后,能在 Local Storage 里观察到 userId 为 current: 这个 current id 从哪里来的呢?在 Spartacus 应用初始 ...

  2. SAP Spartacus 用户登录成功后,Access Token 持久化到浏览器 local storage 的执行原理

    下图第1487行代码,调用Angular HTTP library,往this.tokenEndpoint指向的API发送HTTP post请求,参数为用户在login form里输入的用户名和密码: ...

  3. SAP Spartacus用户登录之后读取用户信息的HTTP请求

    让我有点吃惊的是,如下图所示: 明明我是以中文登录,但这个HTTP请求的url里,lang参数仍然是en: https://spartacus-dev0.eastus.cloudapp.azure.c ...

  4. SAP Spartacus用户登录的实现

    登录界面: 实现Component:login-form.component.html: 上图第1行,触发submitForm函数: 用了promise技术: /*** Authorize with ...

  5. 如何自行找出 SAP Spartacus 查询用户信息的 API Service 类

    成功登录 SAP Spartacus 之后,在 Chrome 开发者工具 Network tab 里能看到一条读取用户信息的网络请求: https://20.83.184.244:9002/occ/v ...

  6. 给SAP Spartacus B2B list增加用户提示信息

    本需求来自Github issue: https://github.com/SAP/spartacus/issues/9991 具体实现: 在负责维护多语言的翻译文件里,增添对应的文本信息: 使用re ...

  7. 如何运行 SAP Spartacus cypress 端到端测试

    首先在本地启动 Spartacus instance, 比如执行 b2c.bat: 进入文件夹:projects/storefrontapp-e2e yarn install: 然后 yarn cy: ...

  8. SAP Spartacus 的会话管理 Session Management

    官网 从一开始,Spartacus 就包含了客户端身份验证和用户身份验证. 尽管这对于 Web 应用程序来说并不常见,但对于 Spartacus 来说是必须的,因为后者需要使用 OCC API. 客户 ...

  9. 关于 SAP Spartacus Loader Meta Reducer 的用途 - loading 在 true 和 false之前切换的逻辑

    为了给用户更好的反馈,基于他们的行为,我们经常需要保留诸如"正在加载购物车"."获取用户地址失败"等信息. 对于每个单独的应用程序状态,我们必须将元数据放在旁边 ...

最新文章

  1. 【组队学习】十二月微信图文索引
  2. C语言程序设计蔺德军,C语言程序设计上机实验与习题解答(第2版)
  3. 实现根据条件删除_Vue源码解析,keep-alive是如何实现缓存的?
  4. TrueNorth:IBM的百万神经元类人脑芯片
  5. iOS开发--TableView详细解释
  6. 2018/Province_Java_A/1/分数
  7. 人脸识别代码_10行代码实现人脸识别
  8. 在同一局域网内的同一工作组内登陆其中的机器时显示输入网络密码对话框
  9. (八)Locust 设置断言
  10. VB与数据库连接方式
  11. 111、锐捷交换机如何配置?一步步详解,交换机配置再也不难了
  12. Navicat自动运行批处理作业并发送附件邮件
  13. 抖音云控系统多少钱一套?
  14. python 滚动字幕_python – 在PyQt中滚动文本?
  15. linux双显卡配置_linux双显卡配置 linux网络配置
  16. 杨幂穿搭有三宝:露腿,收腰,配饰亮点,赶快马起来
  17. 【OpenGL】笔记三、着色器
  18. frameset和frame的使用方法
  19. 单词1(-cess -ceed -cede -gress -gred -grad)=to go、go
  20. 云顶之弈怎么防止被机器人拉_云顶之弈:只有钻石玩家才知道的12个小技巧,都是干货!...

热门文章

  1. 利用angular4和nodejs-express构建一个简单的网站(六)—用户模块和路由分析
  2. ESG里程碑:发布第100份实验室报告
  3. Android 自己定义View须要重写ondraw()等方法
  4. QCOW2/RAW/qemu-img 概念浅析
  5. Azure 中国篇之计算服务—多个站点的×××配置
  6. SQL LIKE 通配符随笔
  7. IronRuby 0.0.1.0
  8. Python基础入门笔记(二)
  9. 第二章:Java_基本语法_5 数组
  10. 问题 1462: [蓝桥杯][基础练习VIP]Huffuman树