I want to build small application. There will be some users. I don't want to make my own user system. I want to integrate my application with oauth/oauth2.0.
我想构建一个小型应用程序。会有一些用户。我不想创建自己的用户系统。我想把我的应用程序集成到oauth/oauth2.0中。
There is no problem in integration of my front-end application and oauth 2.0. There are so many helpful articles, how to do this, even on *.com. For example this post is very helpful.
集成我的前端应用程序和oauth 2.0没有问题。有很多有用的文章,如何做到这一点,即使是在*.com上。例如,这篇文章非常有用。
But. What should I do after successful authorization on front-end? Of course, I can just have flag on client, which says "okay, mate, user is authenticated", but how I should interact with my backend now? I can not just make some requests. Back-end - some application, which provides API functions. EVERYONE can access this api.
但是。在前端获得成功授权后,我应该怎样做?当然,我可以在客户端上有标志,上面写着“好的,伙计,用户是经过认证的”,但是我现在应该如何与后端进行交互呢?我不能只提出一些要求。后端应用程序,提供API功能。每个人都可以访问这个api。
So, I need some auth system anyway between my FE and BE. How this system should work?
所以,无论如何,我需要一些在我的生活和生活之间的真实系统。这个系统应该如何工作?
ps I have some problems with English and may be I can not just correctly 'ask google' about it. Can you provide correct question, please :) or at least give some articles about my question.
ps:我有一些英语方面的问题,可能是我不能正确地问谷歌。你能提供正确的问题吗?)或者至少给一些关于我的问题的文章。
UPD
I am looking for concept. I don't want to find some solution for my current problem. I don't think it is matters which FE and BE I use (anyway I will provide information about it below)
我在寻找概念。我不想为我目前的问题找到解决办法。我认为我使用的FE和BE并不重要(无论如何,我将在下文中提供相关信息)
FE and BE will use JSON for communication. FE will make requests, BE will send JSON responses. My application will have this structure (probably):
FE和BE将使用JSON进行通信。FE将发出请求,BE将发送JSON响应。我的应用程序将具有以下结构(可能):
- Frontend - probably AngularJS
- 前端——也许AngularJS
- Backend - probably Laravel (laravel will implement logic, also there is database in structure)
- 后端——可能是Laravel (Laravel将实现逻辑,而且在结构上也有数据库)
Maybe "service provider" like google.com, vk.com, twitter.com etc remembers state of user? And after successful auth on FE, I can just ask about user state from BE?
也许像google, vk.com, twitter.com这样的“服务提供商”还记得用户的状态?而在FE上成功的auth之后,我就可以从BE中询问用户状态了吗?
6 个解决方案
#1
18
We have 3 main security concerns when creating an API.
在创建API时,我们有三个主要的安全问题。
-
Authentication: An identify provider like Google is only a partial solution. Because you don't want to prompt the user to login / confirm their identity for each API request, you must implement authentication for subsequent requests yourself. You must store, accessible to backend:
身份验证:像谷歌这样的标识提供程序只是部分解决方案。因为您不想提示用户为每个API请求登录/确认他们的身份,所以您必须自己为后续请求实现身份验证。必须存储,后端可访问:
- A user's ID. (taken from the identity provider, for example: email)
- 用户的ID(从身份提供程序中获取,例如:电子邮件)
- A user token. (A temporary token that you generate, and can verify from the API code)
- 用户令牌。(您生成的临时标记,并可以从API代码验证)
-
Authorization: Your backend must implement rules based on the user ID (that's your own business).
授权:后端必须基于用户ID(这是您自己的业务)实现规则。
-
Transport security: HTTPS and expiring cookies are secure and not replayable by others. (HTTPS is encrypting traffic, so defeats man-in-the-middle attacks, and expiring cookies defeats replay attacks later in time)
传输安全性:HTTPS和过期cookie是安全的,其他人不能重新播放。(HTTPS正在加密流量,因此击败了中间人攻击,并且过期的cookie会在稍后的时间内击败重播攻击)
So your API / backend has a lookup table of emails to random strings. Now, you don't have to expose the user's ID. The token is meaningless and temporary.
因此,您的API /后端有一个针对随机字符串的电子邮件查找表。现在,您不必公开用户的ID,该令牌是无意义的、临时的。
Here's how the flow works, in this system:
在这个系统中,流程是这样工作的:
User-Agent IdentityProvider (Google/Twitter) Front-End Back-End
|-----------------"https://your.app.com"---------->|
|---cookies-->|
your backend knows the user or not.
if backend recognizes cookie,
user is authenticated and can use your API
ELSE:
其他:
if the user is unknown:
|<--"unknown"-|
|<----"your/login.js"----------+
"Do you Authorize this app?"
|<------------------+
|--------"yes"----->|
+----------auth token--------->|
|<---------/your/moreinfo.js---|
|-------access_token ---------->|
1. verify access token
2. save new user info, or update existing user
3. generate expiring, random string as your own API token
+----------->|
|<-------------- set cookie: your API token --------------------|
NOW, the user can directly use your API:
现在,用户可以直接使用您的API:
|--------------- some API request, with cookie ---------------->|
|<-------------- some reply, depends on your logic, rules ------|
EDIT
编辑
Based on discussion - adding that the backend can authenticate a user by verifying the access token with the identity provider:
基于讨论——添加后端可以通过身份提供者验证访问令牌对用户进行身份验证:
For example, Google exposes this endpoint to check a token XYZ123
:
例如,谷歌公开此端点以检查令牌XYZ123:
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=XYZ123
#2
3
Well you don'y need User-System on your Front End side. The front end is just a way to interact with your server and ask for token by valid user and password.
你不需要用户系统在前端。前端只是与服务器交互的一种方式,并通过有效的用户和密码请求令牌。
Your server supposed to manage users and the permissions.
您的服务器应该管理用户和权限。
User login scenario
用户登录的场景
User asking for token by entering his username and password. The server-API accept the request because it's anonymous method (everyone can call this method without care if he's logged in or not.
用户通过输入用户名和密码请求令牌。服务器- api接受请求,因为它是匿名方法(每个人都可以不关心自己是否登录了这个方法)。
The server check the DB (Or some storage) and compare the user details to the details he has. In case that the details matches, the server will return token to the user.
服务器检查DB(或一些存储),并将用户细节与他拥有的细节进行比较。如果细节匹配,服务器将返回令牌给用户。
From now, the user should set this token with any request so the server will recognize the user. The token actually hold the user roles, timestamp, etc...
从现在开始,用户应该用任何请求设置这个令牌,以便服务器识别用户。该令牌实际持有用户角色、时间戳等……
When the user request for data by API, it fetch the user token from the header, and check if the user is allowed to access that method.
当用户通过API请求数据时,它从报头获取用户令牌,并检查用户是否允许访问该方法。
That's how it works in generally.
这就是它的工作原理。
I based on .NET in my answer. But the most of the BE libaries works like that.
我的回答是基于。net。但是大部分的图书馆都是这样运作的。
#3
3
I read through all the answers very carefully, and more than half the people who responded are missing the question completely. OP is asking for the INITIAL connection between FE & BE, after the OAuth token has been issued by the Service Provider.
我仔细阅读了所有的答案,超过一半的回答者完全忽略了这个问题。OP要求在服务提供者发出OAuth令牌之后,FE和BE之间进行初始连接。
How does your backend know that the OAuth token is valid? Well keep in mind that your BE can send a request to the Service Provider & confirm the validity of the OAuth token, which was first received by your FE. This OAuth key can be decrypted by the Service Provider only because only they have the secret key. Once they decrypt the key, they usually will respond with information such as username, email and such.
您的后端如何知道OAuth令牌是有效的?请记住,您的BE可以向服务提供商发送请求并确认OAuth令牌的有效性,这是您的FE第一次收到的。这个OAuth密钥可以由服务提供者解密,因为只有他们拥有密钥。一旦他们解密密钥,他们通常会用用户名、电子邮件等信息进行回应。
In summary:
总而言之:
Your FE receives OAuth token from Service Provider after user gives authorization. FE passes OAuth token to BE. BE sends OAuth token to Service Provider to validate the OAuth token. Service Provider responds to BE with username/email information. You can then use the username/email to create an account.
在用户授权之后,您的FE从服务提供者接收OAuth令牌。FE通过OAuth令牌。BE将OAuth令牌发送到服务提供者以验证OAuth令牌。服务提供商使用用户名/电子邮件信息进行响应。然后您可以使用用户名/电子邮件创建一个帐户。
Then after your BE creates the account, your BE should generate its own implementation of an OAuth token. Then you send your FE this OAuth token, and on every request, your FE would send this token in the header to your BE. Since only your BE has the secret key to validate this token, your application will be very safe. You could even refresh your BE's OAuth token on every request, giving your FE a new key each time. In case someone steals the OAuth token from your FE, that token would be quickly invalidated, since your BE would have already created a new OAuth token for your FE.
然后,在您的BE创建帐户之后,您的BE应该生成自己的OAuth令牌实现。然后你将这个OAuth令牌发送给你的FE,在每一个请求中,你的FE都会将这个令牌发送到你的BE。因为只有您的BE具有验证该令牌的密钥,所以您的应用程序将非常安全。您甚至可以在每个请求上刷新BE的OAuth令牌,每次都给您的FE一个新键。如果有人从你的FE中偷了OAuth令牌,该令牌将很快失效,因为你的be已经为你的FE创建了一个新的OAuth令牌。
There's more info on how your BE can validate the OAuth token. How to validate an OAuth 2.0 access token for a resource server?
关于如何验证OAuth令牌,有更多的信息。如何验证资源服务器的OAuth 2.0访问令牌?
#4
2
As am doing a project for SSO and based on my understanding to your question, I can suggest that you create an end-point in your back-end to generate sessions, once the client -frontend- has successfully been authorized by the account owner, and got the user information from the provider, you post that information to the back-end endpoint, the back-end endpoint generates a session and stores that information, and send back the session ID -frequently named jSessionId- with a cookie back to the client -frontend- so the browser can save it for you and every request after that to the back-end considered an authenticated user.
为SSO正在做一个项目,根据我的理解你的问题,我可以建议你在后台创建一个端点生成会话,一旦客户端前端——已经成功被授权的帐户所有者,并得到了用户的信息提供者,你把信息提交给后端端点,后端端点生成会话和存储这些信息,并将会话ID(通常命名为jSessionId)发送回给客户端前端——这样浏览器就可以将它保存给您,并将之后的每个请求保存到后端(经过身份验证的用户)。
to logout, simply create another endpoint in the back-end to accepts a session ID so the back-end can remove it.
要注销,只需在后端创建另一个端点来接受会话ID,以便后端可以删除它。
I hope this be helpful for you.
我希望这对你有帮助。
#5
1
let's use OAuth concept to begin,FE here is Client , BE here is Resource Server.
让我们从OAuth概念开始,FE在这里是客户端,在这里是资源服务器。
- Since your client already authorized, Authorization server should grant Access token to the client.
- 由于您的客户端已经授权,授权服务器应该向客户机授予访问令牌。
- Client make request to the resource server with the Access token
- 客户端使用访问令牌向资源服务器发出请求
- Resource server validate the Access token, if valid, handle the request.
- 资源服务器验证访问令牌,如果有效,处理请求。
You may ask, what is the Access token, Access token was issued by authorization server, grant to client, and recognized by resource server.
您可能会问,什么是访问令牌,访问令牌由授权服务器发出,授予客户端,并由资源服务器识别。
Access token is a string indicate the authorization information(e.g. user info, permission scope, expires time...).
访问令牌是表示授权信息的字符串。用户信息,权限范围,到期时间……)。
Access token may encrypted for security, and you should make sure resource server can decrypt it.
访问令牌可以加密以保证安全性,您应该确保资源服务器可以解密它。
for more details, please read OAuth2.0 specification https://tools.ietf.org/html/rfc6749.
有关详细信息,请阅读OAuth2.0规范https://tools.ietf.org/html/rfc6749。
#6
1
You need to store the token in the state of your app and then pass it to the backend with each request. Passing to backend can be done in headers, cookies or as params - depends on how backend is implemented.
您需要将该令牌存储在应用程序的状态中,然后在每次请求时将其传递到后端。传递到后端可以在header、cookies或params中完成——这取决于后端是如何实现的。
Follow the code to see a good example of all the pieces in action (not my code) This example sets the Authorization: Bearer TOKEN header https://github.com/cornflourblue/angular-registration-login-example
按照代码查看所有正在运行的片段(不是我的代码)的一个很好的示例。这个示例设置了授权:承载令牌头https://github.com/cornflourblue/angular-registration-login-example
#1
18
We have 3 main security concerns when creating an API.
在创建API时,我们有三个主要的安全问题。
-
Authentication: An identify provider like Google is only a partial solution. Because you don't want to prompt the user to login / confirm their identity for each API request, you must implement authentication for subsequent requests yourself. You must store, accessible to backend:
身份验证:像谷歌这样的标识提供程序只是部分解决方案。因为您不想提示用户为每个API请求登录/确认他们的身份,所以您必须自己为后续请求实现身份验证。必须存储,后端可访问:
- A user's ID. (taken from the identity provider, for example: email)
- 用户的ID(从身份提供程序中获取,例如:电子邮件)
- A user token. (A temporary token that you generate, and can verify from the API code)
- 用户令牌。(您生成的临时标记,并可以从API代码验证)
-
Authorization: Your backend must implement rules based on the user ID (that's your own business).
授权:后端必须基于用户ID(这是您自己的业务)实现规则。
-
Transport security: HTTPS and expiring cookies are secure and not replayable by others. (HTTPS is encrypting traffic, so defeats man-in-the-middle attacks, and expiring cookies defeats replay attacks later in time)
传输安全性:HTTPS和过期cookie是安全的,其他人不能重新播放。(HTTPS正在加密流量,因此击败了中间人攻击,并且过期的cookie会在稍后的时间内击败重播攻击)
So your API / backend has a lookup table of emails to random strings. Now, you don't have to expose the user's ID. The token is meaningless and temporary.
因此,您的API /后端有一个针对随机字符串的电子邮件查找表。现在,您不必公开用户的ID,该令牌是无意义的、临时的。
Here's how the flow works, in this system:
在这个系统中,流程是这样工作的:
User-Agent IdentityProvider (Google/Twitter) Front-End Back-End
|-----------------"https://your.app.com"---------->|
|---cookies-->|
your backend knows the user or not.
if backend recognizes cookie,
user is authenticated and can use your API
ELSE:
其他:
if the user is unknown:
|<--"unknown"-|
|<----"your/login.js"----------+
"Do you Authorize this app?"
|<------------------+
|--------"yes"----->|
+----------auth token--------->|
|<---------/your/moreinfo.js---|
|-------access_token ---------->|
1. verify access token
2. save new user info, or update existing user
3. generate expiring, random string as your own API token
+----------->|
|<-------------- set cookie: your API token --------------------|
NOW, the user can directly use your API:
现在,用户可以直接使用您的API:
|--------------- some API request, with cookie ---------------->|
|<-------------- some reply, depends on your logic, rules ------|
EDIT
编辑
Based on discussion - adding that the backend can authenticate a user by verifying the access token with the identity provider:
基于讨论——添加后端可以通过身份提供者验证访问令牌对用户进行身份验证:
For example, Google exposes this endpoint to check a token XYZ123
:
例如,谷歌公开此端点以检查令牌XYZ123:
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=XYZ123
#2
3
Well you don'y need User-System on your Front End side. The front end is just a way to interact with your server and ask for token by valid user and password.
你不需要用户系统在前端。前端只是与服务器交互的一种方式,并通过有效的用户和密码请求令牌。
Your server supposed to manage users and the permissions.
您的服务器应该管理用户和权限。
User login scenario
用户登录的场景
User asking for token by entering his username and password. The server-API accept the request because it's anonymous method (everyone can call this method without care if he's logged in or not.
用户通过输入用户名和密码请求令牌。服务器- api接受请求,因为它是匿名方法(每个人都可以不关心自己是否登录了这个方法)。
The server check the DB (Or some storage) and compare the user details to the details he has. In case that the details matches, the server will return token to the user.
服务器检查DB(或一些存储),并将用户细节与他拥有的细节进行比较。如果细节匹配,服务器将返回令牌给用户。
From now, the user should set this token with any request so the server will recognize the user. The token actually hold the user roles, timestamp, etc...
从现在开始,用户应该用任何请求设置这个令牌,以便服务器识别用户。该令牌实际持有用户角色、时间戳等……
When the user request for data by API, it fetch the user token from the header, and check if the user is allowed to access that method.
当用户通过API请求数据时,它从报头获取用户令牌,并检查用户是否允许访问该方法。
That's how it works in generally.
这就是它的工作原理。
I based on .NET in my answer. But the most of the BE libaries works like that.
我的回答是基于。net。但是大部分的图书馆都是这样运作的。
#3
3
I read through all the answers very carefully, and more than half the people who responded are missing the question completely. OP is asking for the INITIAL connection between FE & BE, after the OAuth token has been issued by the Service Provider.
我仔细阅读了所有的答案,超过一半的回答者完全忽略了这个问题。OP要求在服务提供者发出OAuth令牌之后,FE和BE之间进行初始连接。
How does your backend know that the OAuth token is valid? Well keep in mind that your BE can send a request to the Service Provider & confirm the validity of the OAuth token, which was first received by your FE. This OAuth key can be decrypted by the Service Provider only because only they have the secret key. Once they decrypt the key, they usually will respond with information such as username, email and such.
您的后端如何知道OAuth令牌是有效的?请记住,您的BE可以向服务提供商发送请求并确认OAuth令牌的有效性,这是您的FE第一次收到的。这个OAuth密钥可以由服务提供者解密,因为只有他们拥有密钥。一旦他们解密密钥,他们通常会用用户名、电子邮件等信息进行回应。
In summary:
总而言之:
Your FE receives OAuth token from Service Provider after user gives authorization. FE passes OAuth token to BE. BE sends OAuth token to Service Provider to validate the OAuth token. Service Provider responds to BE with username/email information. You can then use the username/email to create an account.
在用户授权之后,您的FE从服务提供者接收OAuth令牌。FE通过OAuth令牌。BE将OAuth令牌发送到服务提供者以验证OAuth令牌。服务提供商使用用户名/电子邮件信息进行响应。然后您可以使用用户名/电子邮件创建一个帐户。
Then after your BE creates the account, your BE should generate its own implementation of an OAuth token. Then you send your FE this OAuth token, and on every request, your FE would send this token in the header to your BE. Since only your BE has the secret key to validate this token, your application will be very safe. You could even refresh your BE's OAuth token on every request, giving your FE a new key each time. In case someone steals the OAuth token from your FE, that token would be quickly invalidated, since your BE would have already created a new OAuth token for your FE.
然后,在您的BE创建帐户之后,您的BE应该生成自己的OAuth令牌实现。然后你将这个OAuth令牌发送给你的FE,在每一个请求中,你的FE都会将这个令牌发送到你的BE。因为只有您的BE具有验证该令牌的密钥,所以您的应用程序将非常安全。您甚至可以在每个请求上刷新BE的OAuth令牌,每次都给您的FE一个新键。如果有人从你的FE中偷了OAuth令牌,该令牌将很快失效,因为你的be已经为你的FE创建了一个新的OAuth令牌。
There's more info on how your BE can validate the OAuth token. How to validate an OAuth 2.0 access token for a resource server?
关于如何验证OAuth令牌,有更多的信息。如何验证资源服务器的OAuth 2.0访问令牌?
#4
2
As am doing a project for SSO and based on my understanding to your question, I can suggest that you create an end-point in your back-end to generate sessions, once the client -frontend- has successfully been authorized by the account owner, and got the user information from the provider, you post that information to the back-end endpoint, the back-end endpoint generates a session and stores that information, and send back the session ID -frequently named jSessionId- with a cookie back to the client -frontend- so the browser can save it for you and every request after that to the back-end considered an authenticated user.
为SSO正在做一个项目,根据我的理解你的问题,我可以建议你在后台创建一个端点生成会话,一旦客户端前端——已经成功被授权的帐户所有者,并得到了用户的信息提供者,你把信息提交给后端端点,后端端点生成会话和存储这些信息,并将会话ID(通常命名为jSessionId)发送回给客户端前端——这样浏览器就可以将它保存给您,并将之后的每个请求保存到后端(经过身份验证的用户)。
to logout, simply create another endpoint in the back-end to accepts a session ID so the back-end can remove it.
要注销,只需在后端创建另一个端点来接受会话ID,以便后端可以删除它。
I hope this be helpful for you.
我希望这对你有帮助。
#5
1
let's use OAuth concept to begin,FE here is Client , BE here is Resource Server.
让我们从OAuth概念开始,FE在这里是客户端,在这里是资源服务器。
- Since your client already authorized, Authorization server should grant Access token to the client.
- 由于您的客户端已经授权,授权服务器应该向客户机授予访问令牌。
- Client make request to the resource server with the Access token
- 客户端使用访问令牌向资源服务器发出请求
- Resource server validate the Access token, if valid, handle the request.
- 资源服务器验证访问令牌,如果有效,处理请求。
You may ask, what is the Access token, Access token was issued by authorization server, grant to client, and recognized by resource server.
您可能会问,什么是访问令牌,访问令牌由授权服务器发出,授予客户端,并由资源服务器识别。
Access token is a string indicate the authorization information(e.g. user info, permission scope, expires time...).
访问令牌是表示授权信息的字符串。用户信息,权限范围,到期时间……)。
Access token may encrypted for security, and you should make sure resource server can decrypt it.
访问令牌可以加密以保证安全性,您应该确保资源服务器可以解密它。
for more details, please read OAuth2.0 specification https://tools.ietf.org/html/rfc6749.
有关详细信息,请阅读OAuth2.0规范https://tools.ietf.org/html/rfc6749。
#6
1
You need to store the token in the state of your app and then pass it to the backend with each request. Passing to backend can be done in headers, cookies or as params - depends on how backend is implemented.
您需要将该令牌存储在应用程序的状态中,然后在每次请求时将其传递到后端。传递到后端可以在header、cookies或params中完成——这取决于后端是如何实现的。
Follow the code to see a good example of all the pieces in action (not my code) This example sets the Authorization: Bearer TOKEN header https://github.com/cornflourblue/angular-registration-login-example
按照代码查看所有正在运行的片段(不是我的代码)的一个很好的示例。这个示例设置了授权:承载令牌头https://github.com/cornflourblue/angular-registration-login-example