Angular.js中基于OpenID的认证(带有Flask后端) [英] OpenID based authentication in Angular.js (with Flask backend)
问题描述
基于OpenID的身份验证(使用Flask后端Web应用程序)?
如果Angular应用程序发出一个请求到需要认证的服务器,服务器应该返回一个错误代码401.例如,Angular应用程序可以弹出一个登录表单,例如,当它获得一个401。
但是OpenID身份验证跳舞不能在上下文中完成一个丰富的JS应用程序,因为它需要浏览器重定向。您的服务器端应用程序将不得不支持至少三个路径:
$ b $ ul
因此,用户连接到您的根URL并获取AngularJS应用程序,该应用程序以未验证状态启动。在某些时候,Angular应用程序会提示用户登录,使用OpenID文本框的表单提交按钮。这些表单字段应该是发布到服务器的常规HTML表单的一部分,而不是连接到控制器的客户端Angular元素。表单的action属性应指向服务器的OpenID登录路径。
当用户单击登录按钮时,服务器唤醒并接收到启动OpenID的请求认证。在这一步,上面的步骤1-5不加修改地运行。
在步骤5结束时,服务器将用户定位到应用程序的数据库中。服务器现在可以做的是通过重定向回到根URL来重新启动Angular应用程序。如果应用程序需要在非初始状态下重新启动,那么在启动OpenID身份验证过程之前,要还原的状态可以保存在客户端存储(例如,cookie)中。
但这还不够,服务器还需要传递有关登录用户的Angular一些信息。一种方法是将用户的唯一ID或令牌附加到重定向URL的查询字符串中,Angular应用程序可以访问。这将是在上面的步骤6中进入cookie的相同ID。
现在,Angular应用程序重新启动,可以恢复其状态,如果有必要,标识登录用户的ID或标记。当应用程序需要向服务器发送Ajax请求时,它会将此ID或令牌与请求一起发送。服务器可以验证它,并返回401,如果发现它是无效的,或者如果它有一个到期日期,发现过期。
如果与请求一起发送的身份验证然后可以执行请求,并可以将响应发送回Angular应用程序。
注销功能可以在客户端简单地通过删除用户ID /令牌,以便将来对服务器的请求不经身份验证即可发送。
非常重要:Angular应用程序和包含用户信息的Flask服务器必须通过安全的HTTP完成。如果不是,您的ID或令牌将以明文形式出现。
How does one implement OpenID based authentication in Angular.js (with Flask back-end web app)?
It looks like the Angular.js code needs to incorporate logic like the example found here.
However, the Flask side should also have an OpenID verification mechanism.
Is there a "recommended" way to write the logic for both backend and frontend?
Is there a github example or some other related resource for starters?
Unfortunately I do not have a sample application to share, but here is a high level description that I hope is useful.
Let's forget for a moment that you have an AngularJS app and review how the OpenID authentication exchange works:
- User enters OpenID URL in a login form and submits to the server
- The server gets the OpenID URL and responds with a redirect to the OpenID provider. The redirect includes some arguments, including a callback URL.
- The OpenID provider prompts the user to enter login credentials and then to allow the sharing of his/her identify with the server application.
- The OpenID provider responds with a redirect back to the application, at the URL given as a callback in step 2, and makes information about the user such as ID, email, username, etc. available to it.
- The server now has user information and can locate the user in its own user database via the unique ID, the email address or some other piece of identification. At this point a new account can be created if the user is not known to the application.
- Now that the user is known, the server can write a cookie that records who he/she is, but note that this is a different identity than the one in step 5. The identity information returned by the OpenID provider was useful to locate the user in your own database, so now you can record the user's identify in the context of your application. This could be a database user ID, the email address or the username (if they are unique), or a token, which can be a hash of some of the information you have about the user.
- With the cookie written each new request that is sent to the server comes with the data that identifies the authenticated user.
So let's see what happens when you add AngularJS to the mix. Note that there are many ways to do this, what I describe below is one possibility.
If the Angular app issues a request to the server that requires authentication the server should return an error code 401. The Angular app can pop up a login form when it gets a 401, for example.
But the OpenID authentication dance cannot be done all in the context of a rich JS application because it requires browser redirects. Your server side application will have to support at least three routes:
- a root URL that serves the Angular app
- a URL that initiates OpenID authentication
- a URL that is sent as callback to the OpenID provider
So the user connects to your root URL and gets the AngularJS app, which starts in a non-authenticated state. At some point the Angular app will prompt the user to login, using a form that has an OpenID text field an a submit button. These form fields should be part of a regular HTML form that posts to the server, not client-side Angular elements attached to a controller. The "action" attribute of the form should point to the server's OpenID login route.
When the user clicks the login button the server awakens and receives the request to start the OpenID authentication. At this point steps 1-5 above run without change.
At the end of step 5 the server has located the user in the application's database. What the server can do now is respond with a redirect back to the root URL, to get the Angular app restarted. If the app needs to restart in a state that is not the initial state then the state to restore can be saved in client side storage (a cookie, for example) before starting the OpenID authentication process.
But this is not enough, the server also needs to pass Angular some information about the user that logged in. One way to do this is to attach the user's unique ID or token in the query string of the redirect URL, which the Angular app can access. This would be the same piece of ID that went into a cookie in step 6 above.
Now the Angular app is restarted, can restore its state if necessary, and has an ID or token that identifies the logged in user. When the app needs to make an Ajax request to the server it sends this ID or token along with the request. The server can verify it and return 401 if found it is invalid or if it had an expiration date and found to be expired.
If the identification sent with the request is verified then the request can be carried out and a response can be sent back to the Angular app.
A logout function can be implemented in the client-side simply by deleting the user ID/token, so that future requests to the server are sent without authentication again.
Very Important: all exchanges between the Angular app and the Flask server that include user information must be done over secure HTTP. If not your IDs or tokens will be traveling in plain text.
这篇关于Angular.js中基于OpenID的认证(带有Flask后端)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!