使用jwt给api加密_使用JWT构建Rails API

使用jwt给api加密

This is a guide on creating and setting up a Rails API application from scratch.

这是从头开始创建和设置Rails API应用程序的指南。

The focus will be on user login and sign up and authorizing/authenticating them with JWT (JSON Web Tokens). Keep in mind that this approach represents one of many. Let’s begin with the setup.

重点将放在用户登录和注册以及使用JWT( JSON Web令牌 )对其进行授权/认证。 请记住,这种方法代表了众多方法之一。 让我们从设置开始。

建立 (Setup)

Let’s generate a Rails API. From the terminal, run the following command:

让我们生成一个Rails API。 在终端上,运行以下命令:

rails new jwt-rails-api-app --database=postgresql --api

The flag --database=postgresql is included to indicate that PostgreSQL is to be utilized as the database instead of SQLite, and the flag --api is included to indicate that this application is to be set up as an API and to avoid generating the views and view helpers since they are not necessary for an API.

包含--database=postgresql标志以指示将PostgreSQL代替SQLite用作数据库,而包含标志--api则指示将该应用程序设置为API并避免生成该应用程序。查看和查看助手,因为它们对于API而言不是必需的。

Open the newly generated folder and open Gemfile. We need to include a few gems as part of the setup.

打开新生成的文件夹,然后打开Gemfile 。 在安装过程中,我们需要包含一些宝石。

The first is to uncomment/include:

首先是取消注释/包括:

gem 'bcrypt'

Bcrypt will manage hashing the passwords for the user.

Bcrypt将管理用户密码的哈希处理。

The second is to uncomment/include:

第二个是取消注释/包括:

gem 'rack-cors'

This allows the Cross-Origin Resource Sharing (CORS) in the API. CORS prevents API calls from unknown origins.

这允许在API中进行跨域资源共享(CORS)。 CORS阻止来自未知来源的API调用。

And finally, include:

最后,包括:

gem 'jwt'

From the terminal, run bundle install to install the three gems in the application.

在终端上,运行bundle install install将三个gem安装在应用程序中。

Next, navigate to config/initializers/cors.rb and uncomment the following and also replace “example.com” with an asterisk.

接下来,导航至config/initializers/cors.rb并取消注释以下内容,并将“ example.com”替换为星号。

Image for post
CORS
CORS

Now, navigate to config/routes.rb. We will define the routes accessible for this application.

现在,导航到config/routes.rb 。 我们将定义此应用程序可访问的路由。

For this guide, we will only focus on the routes that handle login, signing up a user, and auto-login. We will define a couple of custom routes to handle the login and auto-login.

在本指南中,我们仅关注处理登录,注册用户和自动登录的路由。 我们将定义一些自定义路由来处理登录和自动登录。

Image for post
Routes
路线

For this guide, we will only focus on generating the controller and model for the User. Ideally, the same approach can be taken for others.

对于本指南,我们将仅着重于为User生成控制器和模型。 理想情况下,其他人可以采用相同的方法。

Let’s begin with generating the model for User. We want the following properties for a User instance, :username, :password, and :age.

让我们开始为User生成模型。 我们希望User实例具有以下属性:username:password:age

rails g model User username:string password_digest:string age:integer

Just a few things to note. With :password, if bcrypt is implemented, it is expecting a property of password_digest to hash the password.

只需注意几件事。 使用:password ,如果实现了bcrypt,则期望password_digest的属性对password_digest进行哈希处理。

Important: To ensure this feature is implemented, define the user macro, has_secure_password , in the User model. And finally, generate the User controller with:

重要事项 为了确保实现此功能,请在User模型中定义用户宏has_secure_password 。 最后,生成User控制器 与:

rails g controller Users

The model, controller, and routes for User are now set. Now, let’s run:

现在设置了User的模型,控制器和路由。 现在,让我们运行:

rails db:create && rails db:migrate

For test purposes, we can create one User instance in the db/seeds.rb file.

为了进行测试,我们可以在db/seeds.rb文件中创建一个User实例。

user = User.create(username: "reizl", password: "sample", age: 27)

To seed the database, run rails db:seed. Now that the setup is finished and we have data to work with, we can now focus on the methods of controller.

要播种数据库,请运行rails db:seed 。 既然设置已经完成,并且我们有需要处理的数据,我们现在可以专注于控制器的方法。

应用控制器方法 (Application Controller Methods)

Let’s focus on the application controller. Methods defined in this controller can be accessible in other controllers such as the User. There are many methods defined here, essential to authenticate and authorize users.

让我们专注于应用程序控制器。 可以在其他控制器(例如User访问此控制器中定义的方法。 这里定义了许多方法,这些方法对于验证和授权用户至关重要。

Encode_token (Encode_token)

Let’s begin with encode_token. When this method is invoked later, an object is sent as the argument.

让我们从encode_token开始。 稍后调用此方法时,将发送一个对象作为参数。

The method encode provided by the JWT gem will be utilized to generate a token. JWT.encode takes two arguments, the payload object and a string that represents a “secret”. The method encode_token will return the token generated by JWT.

JWT gem提供的encode方法将用于生成令牌。 JWT.encode接受两个参数, payload对象和代表“秘密”的字符串。 方法encode_token将返回JWT生成的令牌。

Now, with the rest of the methods, it would be more beneficial to explain starting from authorized and working our way up, considering that is the chain of events it takes. There will be some jumping back and forth between methods.

现在,使用其他方法,考虑到这是需要处理的一系列事件,从authorized开始并逐步进行解释将更加有益。 方法之间会有一些来回跳跃。

Before exploring the methods, the macro, before_action :authorized, essentially says that if any request is made to this API, the method, authorized, will always be called first.

在探索这些方法之前,宏before_action :authorized本质上说,如果对此API提出了任何请求,则将始终首先调用authorized方法。

已授权 (Authorized)

As the name implies, this method checks whether a user is authorized. But it is dependent on a chain of methods.

顾名思义,此方法检查用户是否被授权。 但这取决于一系列方法。

If a user is not logged in or a request is not sending the necessary credentials, this method will send back a JSON response, asking them to log in. To determine that information, the method logged_in? is called.

如果用户未登录或请求未发送必要的凭据,则此方法将发送回JSON响应,要求他们登录。要确定该信息,请使用logged_in?方法logged_in? 叫做。

Again, as the name implies, it checks if a user is logged in or not. The logged_in? method returns true or false, depending on the return value of another method called inside of it.

再次,顾名思义,它检查用户是否已登录。 已logged_in? 方法返回true或false,这取决于在其内部调用的另一个方法的返回值。

登录用户 (Logged in user)

The method logged_in_user calls, bear with me now, another method, decoded_token. From decoded_token, the auth_header method is called, which is looking at the information of the request.

现在让我来接受方法logged_in_user调用另一个方法decoded_token 。 从decoded_token ,调用auth_header方法,该方法正在查看请求的信息。

The method is only concerned with the headers, specifically the key of “Authorization”. Ideally, this will contain a token generated by JWT and will be in the format of Bearer <token>, which is what auth_header will return.

该方法仅与标题有关,特别是“授权”的密钥。 理想情况下,它将包含JWT生成的令牌,格式为Bearer <token> ,这是auth_header将返回的内容。

To get just the token, we will use the .split(" ")[1] method on Bearer <token> . Once the token is grabbed and assigned to the token variable, the decode method provided by JWT will be utilized.

为了只获取令牌,我们将在Bearer <token>上使用.split(" ")[1]方法。 一旦令牌被获取并分配给令牌变量,将使用JWT提供的decode方法。

JWT.decode takes in four arguments, the token to decode, the secret string that was assigned when encoding, a true value, and the algorithm (‘HS256’ here). Otherwise, if there is an error, it will return nil.

JWT.decode接受四个参数,即要解码的令牌,编码时分配的秘密字符串,真实值和算法(此处为“ HS256”)。 否则,如果有错误,它将返回nil。

The return value for decoded_token will represent an array from JWT.decode. We’re only concerned with the first index, which will be an object with a key of “user_id.” (this will come from the User’s controller).

为返回值decoded_token将代表从数组JWT.decode 。 我们只关心第一个索引,它将是一个键为“ user_id ”的对象。 (这将来自User的控制器)。

From that “user_id”, we can determine if a User instance with that specific ID exists in the database. If there is, the user is “authorized”, if not, they are not.

根据该“ user_id ”,我们可以确定数据库中是否存在具有该特定ID的User实例。 如果存在,则对用户进行“授权”,否则,则没有。

(Feel free to read again since a sequence of methods is involved.)

(由于涉及到一系列方法,请随时再次阅读。)

用户控制器 (User’s Controller)

Now, let’s shift the focus to the User’s controller. We will focus on the user login, user sign-up (create user), and auto-login of a user. Many of the methods rely on the ones defined in the application controller.

现在,让我们将焦点转移到用户的控制器上。 我们将专注于用户登录,用户注册(创建用户)和用户自动登录。 许多方法依赖于应用程序控制器中定义的方法。

Let’s start off with the macro, before_action :authorized, only: [:auto_login].

让我们从before_action :authorized, only: [:auto_login]宏开始before_action :authorized, only: [:auto_login]

Similar to earlier, we are stating that if any route is accessed in application, the authorized method in application controller runs first. But it is only specific to the route, auto_login. That means that create or login can be accessed directly.

与前面类似,我们声明如果在应用程序中访问了任何路由,则将首先运行应用程序控制器中的authorized方法。 但这仅特定于路由auto_login 。 这意味着可以直接访问createlogin

创造 (Create)

When a user is signing up, a new user instance is being created in the back end. A POST request will be made to /users which will be redirected to the user controller create method.

用户注册时,将在后端创建一个新的用户实例。 将向/users发出POST请求,该请求将重定向到用户控制器create方法。

Let’s examine what is happening in the create method.

让我们检查一下create方法中正在发生的事情。

A user instance is created. If it is valid, a payload object is created with the user instance’s ID and passed into the encode_token method, which is defined in the application controller. The payload object can contain more than one key if needed.

用户实例已创建。 如果有效,则会使用用户实例的ID创建有效负载对象,并将其传递到在应用程序控制器中定义的encode_token方法。 如果需要,有效负载对象可以包含多个密钥。

As discussed earlier, encode_token will return a token string generated by JWT. A JSON object is rendered with the key-value pairs of the user and token as a response.

如前所述, encode_token将返回JWT生成的令牌字符串。 使用用户和令牌的键值对作为响应来呈现JSON对象。

登录 (Login)

A similar approach is implemented when an existing user logs in. But instead, a POST request will be made to /login which will be redirected to the user controller login method.

现有用户登录时,将实现类似的方法。但是,将对/login发出POST请求,该请求将重定向到用户控制器的login方法。

The difference is that we’re checking for an existing user instance from the params passed, specifically the username, using the find_by method. Then, the authenticate method provided by bcrypt compares if the password passed from the params and the password stored in the database match.

不同之处在于,我们正在使用find_by方法从传递的参数(特别是用户名)中检查现有的用户实例。 然后, bcrypt提供的authenticate方法比较从params传递的密码和存储在数据库中的密码是否匹配。

If both the user instance and the authenticate method pass, a token is generated by JWT and a JSON object is rendered with the key-value pairs of the user and token and sent as a response.

如果用户实例和authenticate方法都通过,则JWT将生成令牌,并使用用户和令牌的键值对呈现JSON对象,并将其作为响应发送。

自动登录 (Auto-login)

Let’s examine the auto_login method located in user controller.

让我们检查auto_login位于用户控制器中的auto_login方法。

There’s really not much going on here. The big question is where the variable @user comes from?

这里确实没有太多事情。 最大的问题是变量@user来自何处?

Since the method, authorized, will run before auto_login, the chain of methods in the application controller will also run. One of the methods, logged_in_user, will return a global @user variable that is accessible.

由于方法authorized将在应用程序控制器中的方法链auto_login之前运行 也将运行。 其中一个方法,的logged_in_user ,会返回一个全局@user变量访问。

结束语 (Closing Remarks)

With the routes and methods defined, our Rails API is set! We can run our server using rails s or rails s -p 4000 (if you want to run on a different port).

定义好路由和方法后,我们的Rails API就设置好了! 我们可以使用rails srails s -p 4000运行服务器(如果要在其他端口上运行)。

To test the routes and functionality, we can utilize Postman or connect from a client-side application such as React. Testing the routes and functionality will not be covered in this guide.

要测试路由和功能,我们可以利用Postman或从客户端应用程序(例如React)进行连接。 本指南将不涉及测试路由和功能。

This guide focuses on the set up of a rails API with bcrypt hashing with JWT integrated to handle user authentication/authorization.

本指南重点介绍通过集成了JWT的bcrypt哈希处理Rails API的设置,以处理用户身份验证/授权。

It also covers the logical process behind the methods implemented. Hopefully, this guide has provided guidance on structuring your Rails API with JWT. Thank you for reading!

它还涵盖了所实现方法背后的逻辑过程。 希望本指南提供了有关使用JWT构建Rails API的指南。 感谢您的阅读!

Refer to my repository for details:

请参阅我的存储库以获取详细信息:

翻译自: https://medium.com/better-programming/build-a-rails-api-with-jwt-61fb8a52d833

使用jwt给api加密

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值