博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
angular 异步验证_使用Angular 4和Flask进行用户身份验证
阅读量:2516 次
发布时间:2019-05-11

本文共 18634 字,大约阅读时间需要 62 分钟。

angular 异步验证

In this tutorial, we’ll demonstrate how to set up token-based authentication (via JSON Web Tokens) with Angular 4 and Flask.

在本教程中,我们将演示如何使用Angular 4和Flask设置基于令牌的身份验证(通过JSON Web令牌)。

angular4 auth

Main Dependencies:

主要依赖项:

  1. Angular v (via Angular CLI v)
  2. Flask v
  3. Python v
  1. Angular v (通过Angular CLI v )
  2. 烧瓶v
  3. Python v

验证工作流程 (Auth Workflow)

Here’s the full user auth process:

这是完整的用户身份验证过程:

  1. Client logs in and the credentials are sent to the server
  2. If the credentials are correct, the server generates a token and sends it as a response to the client
  3. Client receives and stores the token in Local Storage
  4. Client then sends token to server on subsequent requests within the request header
  1. 客户端登录并将凭据发送到服务器
  2. 如果凭据正确,则服务器将生成令牌并将其作为响应发送给客户端
  3. 客户端接收令牌并将其存储在本地存储中
  4. 然后,客户端在请求标头中的后续请求上向服务器发送令牌

项目设置 (Project Setup)

Start by globally installing the :

首先全局安装 :

11

Then generate a new Angular 4 project boilerplate:

然后生成一个新的Angular 4项目样板:

11

Fire up the app after the dependencies install:

安装依赖项后启动应用程序:

1122

It will probably take a minute or two to compile and build your application. Once done, navigate to to ensure the app is up and running.

编译和构建应用程序可能需要一两分钟。 完成后,导航到以确保该应用程序已启动并正在运行。

Open up the project in your favorite code editor, and then glance over the code:

在您喜欢的代码编辑器中打开项目,然后浏览一下代码:

11223344556677889910101111121213131414151516161717181819192020212122222323242425252626272728282929

In short, the client-side code lives in the “src” folder and the Angular app itself can be found in the “app” folder.

简而言之,客户端代码位于“ src”文件夹中,而Angular应用本身可在“ app”文件夹中找到。

Take note of the AppModule within app.module.ts. This is used to bootstrap the Angular app. The @NgModule decorator takes metadata that lets Angular know how to run the app. Everything that we create in this tutorial will be added to this object.

注意AppModule中的AppModule。 这用于引导Angular应用程序。 @NgModule装饰器采用元数据,该数据使Angular知道如何运行该应用程序。 我们在本教程中创建的所有内容都将添加到该对象。

Make sure you have a decent grasp of the app structure before moving on.

在继续之前,请确保您对应用程序的结构有很好的了解。

NOTE: Just getting started with Angular 4? Review the , since the app generated from the CLI follows the recommended structure from that guide, as well as the .

注意:刚开始使用Angular 4? 查看 ,因为从CLI生成的应用程序遵循该指南的推荐结构,以及 。

Did you notice that the CLI initialized a new Git repo? This part is optional, but it’s a good idea to create a new Github repository and update the remote:

您是否注意到CLI初始化了一个新的Git存储库? 这部分是可选的,但最好创建一个新的Github存储库并更新远程:

11

Now, let’s wire up a new …

现在,让我们连接一个新 ……

验证组件 (Auth Component)

First, use the CLI to generate a new Login component:

首先,使用CLI生成一个新的Login组件:

11

This set up the component files and folders and even wired it up to app.module.ts. Next, let’s change the login.component.ts file to the following:

这将设置组件文件和文件夹,甚至将其连接到app.module.ts。 接下来,让我们将login.component.ts文件更改为以下内容:

11223344556677889910101111

If you haven’t used before, then this code probably looks pretty foreign to you. TypeScript is a statically-typed superset of JavaScript that compiles to vanilla JavaScript, and it is the de facto programming language for building Angular 4 apps.

如果您以前没有使用过 ,那么这段代码对您来说可能看起来很陌生。 TypeScript是JavaScript的静态类型超集,可编译为原始JavaScript,它是用于构建Angular 4应用程序的事实上的编程语言。

In Angular 4, we define a component by wrapping a config object with an @Component decorator. We can share code between packages by importing the classes we need; and, in this case, we import Component from the @angular/core package. The LoginComponent class is the component’s controller, and we use the export operator to make it available for other classes to import.

在Angular 4中,我们通过使用@Component装饰器包装配置对象来定义组件。 我们可以通过导入所需的类在程序包之间共享代码。 在这种情况下,我们从@angular/core包中导入ComponentLoginComponent类是组件的控制器,我们使用export运算符使其可用于其他类的导入。

Add the following HTML to the login.component.html:

将以下HTML添加到login.component.html中:

112233

Next, configure the routes, via the in the app.module.ts file:

接下来,配置路由,通过在app.module.ts文件:

11223344556677889910101111121213131414151516161717181819192020212122222323

Finish enabling routing by replacing all HTML in the app.component.html file with the <router-outlet> tag:

通过使用<router-outlet>标记替换app.component.html文件中的所有HTML,完成启用路由:

11

Run ng serve in your terminal, if you haven’t already, and then navigate to . If all went well you should see the just a test text.

如果尚未在终端中运行ng serve ,请导航至 。 如果一切顺利,您应该just a test看到just a test文本。

引导样式 (Bootstrap Style)

To quickly add some style, update the index.html, adding in and wrapping the <app-root></app-root> in a :

要快速添加某种样式,请更新index.html,添加并将<app-root></app-root>包装在 :

1122334455667788991010111112121313141415151616

You should see the app auto reload as soon as you save.

保存后,您应该会看到该应用程序自动重新加载。

验证服务 (Auth Service)

Next, let’s create a global to handle a user logging in, logging out, and signing up:

接下来,让我们创建一个全局来处理用户登录,注销和注册:

11

Edit the auth.service.ts so that it has the following code:

编辑auth.service.ts,使其具有以下代码:

1122334455667788

Remember how providers worked in Angular 1? They were global objects that stored a single state. When the data in a provider changed, any object that had injected that provider would receive the updates. In Angular 4, providers retain their special behavior and they are defined with the @Injectable decorator.

还记得提供商在Angular 1中的工作方式吗? 它们是存储单个状态的全局对象。 当提供程序中的数据更改时,注入该提供程序的任何对象都将接收更新。 在Angular 4中,提供程序保留其特殊行为,并使用@Injectable装饰器进行定义。

完整性检查 (Sanity Check)

Before adding anything significant to AuthService, let’s make sure the service itself is wired up correctly. To do that, within login.component.ts inject the service and call the test() method:

在向AuthService添加重要内容之前,请确保服务本身已正确连接。 为此,在login.component.ts中注入服务并调用test()方法:

1122334455667788991010111112121313141415151616

We’ve introduced some new concepts and keywords. The constructor() function is a special method that we use to set up a new instance of a class. The constructor() is where we pass any parameters that the class requires, including any providers (i.e., AuthService) that we want to inject. In TypeScript, we can hide variables from the outside world with the private keyword. Passing a private variable in the constructor is a shortcut to defining it within the class and then assigning the argument’s value to it. Notice how the auth variable is accessible to the this object after it is passed into the constructor.

我们介绍了一些新概念和关键字。 constructor()函数是一种特殊的方法,我们使用它来建立类的新实例。 constructor()是我们传递类所需的任何参数的地方,包括我们要注入的任何提供程序(即AuthService )。 在TypeScript中,我们可以使用private关键字隐藏外界的变量。 在构造函数中传递private变量是在类中定义它,然后为其分配参数值的快捷方式。 请注意,在this对象传递到构造函数之后, auth变量如何可访问this对象。

We implement the OnInit interface to ensure that we explicitly define a ngOnInit() function. Implementing OnInit ensures that our component will be called after the first change detection check. This function is called once when the component first initializes, making it the ideal place to configure data that relies on other Angular classes.

我们实现OnInit接口以确保我们明确定义ngOnInit()函数。 实施OnInit可确保在第一次更改检测检查之后调用我们的组件。 组件首次初始化时,将调用此函数一次,使其成为配置依赖于其他Angular类的数据的理想场所。

Unlike components, which are automatically added, services have to be manually imported and configured on the @NgModule. So, to get it working, you’ll also have to import the AuthService in app.module.ts and add it to the providers:

与自动添加的组件不同,必须在@NgModule上手动导入和配置@NgModule 。 因此,要使其正常工作,您还必须在AuthService中导入AuthService并将其添加到providers

112233445566778899101011111212131314141515161617171818191920202121222223232424

Run the server and then navigate to . You should see working logged to the JavaScript console.

运行服务器,然后导航到 。 您应该看到将working记录到JavaScript控制台。

用户登录 (User Login)

To handle logging a user in, update the AuthService like so:

要处理用户登录, AuthService像这样更新AuthService

11223344556677889910101111121213131414

We employ the help of some built-in Angular classes, Headers and Http, to handle our AJAX calls to the server.

我们利用一些内置的Angular类HeadersHttp的帮助来处理对服务器的AJAX调用。

Also, update the app.module.ts file to import the HttpModule.

另外,更新app.module.ts文件以导入HttpModule

11223344556677889910101111121213131414151516161717181819192020212122222323242425252626

Here, we are using the Http service to send an AJAX request to the /user/login endpoint. This returns a promise object.

在这里,我们使用Http服务将AJAX请求发送到/user/login端点。 这将返回一个Promise对象。

NOTE: Make sure to remove console.log(this.auth.test()); from the LoginComponent component.

注意:确保删除console.log(this.auth.test());LoginComponent组件。

用户注册 (User Registration)

Let’s go ahead and add the ability to register a user as well, which is similar to logging a user in. Update src/app/services/auth.service.ts, taking note of the register method:

让我们继续并添加注册用户的功能,这类似于登录用户。更新src / app / services / auth.service.ts,注意register方法:

112233445566778899101011111212131314141515161617171818

Now, to test this we need to set up a back end…

现在,要对此进行测试,我们需要设置一个后端…

服务器端设置 (Server-side Setup)

For the server-side, we’ll use the finished project from a previous blog post, . You can view the code from the repository.

对于服务器端,我们将使用先前博客文章完成的项目。 您可以从存储库查看代码。

NOTE: Feel free to use your own server, just make sure to update the baseURL in the AuthService.

注意:随意使用您自己的服务器,只需确保更新baseURL中的AuthService

Clone the project structure in a new terminal window:

在新的终端窗口中克隆项目结构:

11

Follow the directions in the to set up the project, making sure the tests pass before moving on. Once done, run the server with python manage.py runserver, which will listen on port 5000.

按照中的说明设置项目,并在继续进行之前确保测试通过。 完成后,使用python manage.py runserver运行服务器,它将侦听端口5000。

完整性检查 (Sanity Check)

To test, update LoginComponent to use the login and register methods from the service:

要测试,请更新LoginComponent以使用服务中的loginregister方法:

1122334455667788991010111112121313141415151616171718181919202021212222232324242525262627272828292930303131

Refresh in the browser and you should see a success in the JavaScript console, after the user is logged in, with the token:

在浏览器中刷新 ,并在用户登录后使用以下令牌在JavaScript控制台中看到成功:

1122334455

验证登录 (Auth Login)

Update login.component.html:

更新login.component.html:

11223344556677889910101111121213131414151516161717

Take note of the form. We used the [(ngModel)] directive on each of the form inputs to capture those values in the controller. Also, when the form is submitted, the ngSubmit directive handles the event by firing the onLogin() method.

注意表格。 我们在每个表单输入上使用了[(ngModel)]指令,以捕获控制器中的这些值。 另外,提交表单时, ngSubmit指令通过触发onLogin()方法来处理事件。

Now, let’s update the component code, adding in onLogin():

现在,让我们更新组件代码,添加onLogin()

1122334455667788991010111112121313141415151616171718181919202021212222

If you have the Angular web server running, you should see the error Cannot find module '../../models/user' in the browser. Before our code will work, we need to create a User model.

如果您正在运行Angular Web服务器,则应该在浏览器中看到错误Cannot find module '../../models/user' 。 在我们的代码生效之前,我们需要创建一个User模型。

11

Update src/app/models/user.ts:

更新src / app / models / user.ts:

112233

Our User model has two properties, email and password. The ? character is a special operator that indicates that initializing User with explicit email and password values is optional. This is equivalent to the following class in Python:

我们的User模型具有两个属性, emailpassword? 字符是一个特殊的运算符,它指示使用显式的emailpassword值初始化User是可选的。 这等效于Python中的以下类:

11223344

Don’t forget to update auth.service.ts to use the new object.

不要忘记更新auth.service.ts以使用新对象。

1122334455667788991010111112121313141415151616171718181919

One last thing. We need to import the FormsModule in the app.module.ts file.

最后一件事。 我们需要导入FormsModule在app.module.ts文件。

1122334455667788991010111112121313141415151616171718181919202021212222232324242525262627272828

So, when the form is submitted, we capture the email and password and pass them to the login() method on the service.

因此,提交表单后,我们将捕获电子邮件和密码,并将它们传递给服务上的login()方法。

Test this out with-

用-测试一下

  • email: michael@realpython.com
  • password: michael
  • 电子邮件: michael@realpython.com
  • 密码: michael

Again, you should see a success in the javaScript console with the token.

同样,您应该在带有令牌的javaScript控制台中看到成功。

认证注册 (Auth Register)

Just like for the login functionality, we need to add a component for registering a user. Start by generating a new Register component:

就像登录功能一样,我们需要添加一个组件来注册用户。 首先生成一个新的Register组件:

11

Update src/app/components/register/register.component.html

更新src / app / components / register / register.component.html

11223344556677889910101111121213131414151516161717

Then, update src/app/components/register/register.component.ts as follows:

然后,如下更新src / app / components / register / register.component.ts:

1122334455667788991010111112121313141415151616171718181919202021212222

Add a new route handler to the app.module.ts file:

将新的路由处理程序添加到app.module.ts文件:

11223344

Test it out by registering a new user!

通过注册新用户进行测试!

本地存储 (Local Storage)

Next, let’s add the token to Local Storage for persistence by replacing the console.log(user.json()); with localStorage.setItem('token', user.data.token); in src/app/components/login/login.component.ts:

接下来,让我们通过替换console.log(user.json());将令牌添加到本地存储以实现持久性console.log(user.json());localStorage.setItem('token', user.data.token); 在src / app / components / login / login.component.ts中:

112233445566778899

Do the same within src/app/components/register/register.component.ts:

在src / app / components / register / register.component.ts中执行相同的操作:

112233445566778899

As long as that token is present, the user can be considered logged in. And, when a user needs to make an AJAX request, that token can be used.

只要存在该令牌,就可以认为该用户已登录。并且,当用户需要发出AJAX请求时,可以使用该令牌。

NOTE: Besides the token, you could also add the user id and email to Local Storage. You would just need to update the server-side to send back that info when a user logs in.

注意:除了令牌,您还可以将用户ID和电子邮件添加到本地存储。 您只需要更新服务器端即可在用户登录时发回该信息。

Test this out. Ensure that the token is present in Local Storage after you log in.

测试一下。 登录后,确保令牌在本地存储中存在。

用户状态 (User Status)

To test out login persistence, we can add a new view that verifies that the user is logged in and that the token is valid.

为了测试登录持久性,我们可以添加一个新视图来验证用户是否已登录以及令牌是否有效。

Add the following method to AuthService:

将以下方法添加到AuthService

1122334455667788

Take note of Authorization: 'Bearer ' + token. This is called a , which is sent along with the request. On the server, we are simply checking for the Authorization header, and then whether the token is valid. Can you find this code on the server-side?

注意Authorization: 'Bearer ' + token 。 这称为 ,它与请求一起发送。 在服务器上,我们只需检查Authorization标头,然后检查令牌是否有效。 您可以在服务器端找到此代码吗?

Then, generate a new Status component:

然后,生成一个新的Status组件:

11

Create the HTML template, src/app/components/status/status.component.html:

创建HTML模板src / app / components / status / status.component.html:

11223344556677

And change the component code in src/app/components/status/status.component.ts:

并在src / app / components / status / status.component.ts中更改组件代码:

112233445566778899101011111212131314141515161617171818191920202121222223232424252526262727

Finally, add a new route handler to the app.module.ts file:

最后,将新的路由处理程序添加到app.module.ts文件:

1122334455

Ready to test? Log in, and then navigate to . If there is a token in Local Storage, you should see:

准备测试了吗? 登录,然后导航到 。 如果本地存储中有令牌,则应该看到:

11223344

Why? Well, if you dig deeper on the server-side, you will find that the token is only valid for 5 seconds in project/server/models.py:

为什么? 好吧,如果您在服务器端进行更深入的研究,您会发现该令牌在project / server / models.py中仅有效5秒钟:

112233445566778899101011111212131314141515161617171818

Update this to 1 day:

更新至1天:

11

And then test it again. You should now see something like:

然后再次测试。 您现在应该看到类似以下内容:

112233445566778899

Finally, let’s redirect to the status page after a user successfully registers or logs in. Update src/app/components/login/login.component.ts like so:

最后,让我们在用户成功注册或登录后重定向到状态页面。像这样更新src / app / components / login / login.component.ts:

112233445566778899101011111212131314141515161617171818191920202121222223232424

Then update src/app/components/register/register.component.ts:

然后更新src / app / components / register / register.component.ts:

112233445566778899101011111212131314141515161617171818191920202121222223232424

Test it out!

测试一下!

路线限制 (Route Restriction)

Right now, all routes are open; so, regardless of whether a user is logged in or not, they they can access each route. Certain routes should be restricted if a user is not logged in, while other routes should be restricted if a user is logged in:

现在,所有路线都开放; 因此,无论用户是否登录,他们都可以访问每个路由。 如果用户未登录,则应限制某些路由,而如果用户已登录,则应限制其他路由:

  1. / – no restrictions
  2. /login – restricted when logged in
  3. /register – restricted when logged in
  4. /status – restricted when not logged in
  1. / –无限制
  2. /login/login受限制
  3. /register –登录时受限制
  4. /status –在未登录时受限制

To achieve this, add either EnsureAuthenticated or LoginRedirect to each route, depending on whether you want to guide the user to the status view or the login view.

为此,请根据您是要引导用户进入status视图还是login视图,向每条路由添加EnsureAuthenticatedLoginRedirect

Start by creating two new services:

首先创建两个新服务:

1122

Replace the code in the ensure-authenticated.service.ts file as follows:

如下所示,确保代码中的代码替换为sure-authenticated.service.ts:

11223344556677889910101111121213131414151516161717

And replace the code in the login-redirect.service.ts like so:

并像下面这样替换login-redirect.service.ts中的代码:

11223344556677889910101111121213131414151516161717

Finally, update the app.module.ts file to import and configure the new services:

最后,更新app.module.ts文件以导入和配置新服务:

11223344556677889910101111121213131414151516161717181819192020212122222323242425252626272728282929303031313232333334343535363637373838393940404141424243434444454546464747484849495050515152525353

Note how we are adding our services to a new route property, canActivate. The routing system uses the services in the canActivate array to determine whether to display the requested URL path. If the route has LoginRedirect and the user is already logged in, then they will be redirected to the status view. Including the EnsureAuthenticated service redirects the user to the login view if they attempt to access a URL that requires authentication.

注意我们如何将服务添加到新的路由属性canActivate 。 路由系统使用canActivate数组中的服务来确定是否显示请求的URL路径。 如果路由具有LoginRedirect并且用户已经登录,则他们将被重定向到status视图。 如果用户尝试访问需要身份验证的URL,则将其包括在内的EnsureAuthenticated将用户重定向到login视图。

Test one last time.

最后一次测试。

下一步是什么? (What’s Next?)

In this tutorial, we went through the process of adding authentication to an Angular 4 + Flask app using JSON Web Tokens.

在本教程中,我们介绍了使用JSON Web令牌向Angular 4 + Flask应用程序添加身份验证的过程。

What’s next?

下一步是什么?

Try switching out the Flask back-end for a different web framework, like Django or Bottle, using the following endpoints:

尝试使用以下端点将Flask后端切换到其他Web框架(如Django或Bottle),例如:

  • /auth/register
  • /auth/login
  • /auth/logout
  • /auth/user
  • /auth/register
  • /auth/login
  • /auth/logout
  • /auth/user

翻译自:

angular 异步验证

转载地址:http://nvqwd.baihongyu.com/

你可能感兴趣的文章
第二天作业
查看>>
访问属性和访问实例变量的区别
查看>>
Spring MVC 异常处理 - SimpleMappingExceptionResolver
查看>>
props 父组件给子组件传递参数
查看>>
【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT
查看>>
十二种获取Spring的上下文环境ApplicationContext的方法
查看>>
UVA 11346 Probability 概率 (连续概率)
查看>>
linux uniq 命令
查看>>
Openssl rand命令
查看>>
HDU2825 Wireless Password 【AC自动机】【状压DP】
查看>>
BZOJ1015: [JSOI2008]星球大战starwar【并查集】【傻逼题】
查看>>
HUT-XXXX Strange display 容斥定理,线性规划
查看>>
mac修改用户名
查看>>
一道关于员工与部门查询的SQL笔试题
查看>>
Canvas基础
查看>>
[Hive - LanguageManual] Alter Table/Partition/Column
查看>>
可持久化数组
查看>>
去除IDEA报黄色/灰色的重复代码的下划波浪线
查看>>
Linux发送qq、网易邮件服务配置
查看>>
几道面试题
查看>>