Rails API With Authentication Si

作者: 臻有一扑 | 来源:发表于2016-03-28 22:50 被阅读1538次

    Installation

    Add the following to your Gemfile:

    gem 'devise_token_auth'
    gem 'devise', '~> 4.0.0.rc1'
    

    Then install the gem using bundle:

    bundle install
    

    Creating User Model and Migration

    Next, let's create a model for authentication.

    rails g devise_token_auth:install User auth
    

    It will return such things at console:

    Running via Spring preloader in process 78994
          create  config/initializers/devise_token_auth.rb
          create  db/migrate/20160328130022_devise_token_auth_create_users.rb
          create  app/models/user.rb
          insert  app/controllers/application_controller.rb
            gsub  config/routes.rb
    

    Since we don't need omniauth at the moment, we should remove the configure(:omniauthable) in model:

    class User < ActiveRecord::Base
      # Include default devise modules.
      devise :database_authenticatable, :registerable,
              :recoverable, :rememberable, :trackable, :validatable,
              :confirmable
      include DeviseTokenAuth::Concerns::User
    end
    

    Migration comes next!

    rake db:migrate
    

    We may get an error while using devise that version is lower that 4.0.0:

    DEPRECATION WARNING: alias_method_chain is deprecated. Please, use Module#prepend instead.....
    NameError: uninitialized constant ActionController::RackDelegation...
    

    Routes

    Run this command to show all routes:

    rake routes
    

    The result is:

    Prefix Verb URI Pattern Controller#Action
    new_user_session GET /auth/sign_in(.:format) devise_token_auth/sessions#new
    user_session POST /auth/sign_in(.:format) devise_token_auth/sessions#create
    destroy_user_session DELETE /auth/sign_out(.:format) devise_token_auth/sessions#destroy
    user_password POST /auth/password(.:format) devise_token_auth/passwords#create
    new_user_password GET /auth/password/new(.:format) devise_token_auth/passwords#new
    edit_user_password GET /auth/password/edit(.:format) devise_token_auth/passwords#edit
    PATCH /auth/password(.:format) devise_token_auth/passwords#update
    PUT /auth/password(.:format) devise_token_auth/passwords#update
    cancel_user_registration GET /auth/cancel(.:format) devise_token_auth/registrations#cancel
    user_registration POST /auth(.:format) devise_token_auth/registrations#create
    new_user_registration GET /auth/sign_up(.:format) devise_token_auth/registrations#new
    edit_user_registration GET /auth/edit(.:format) devise_token_auth/registrations#edit
    PATCH /auth(.:format) devise_token_auth/registrations#update
    PUT /auth(.:format) devise_token_auth/registrations#update
    DELETE /auth(.:format) devise_token_auth/registrations#destroy
    user_confirmation POST /auth/confirmation(.:format) devise_token_auth/confirmations#create
    new_user_confirmation GET /auth/confirmation/new(.:format) devise_token_auth/confirmations#new
    GET /auth/confirmation(.:format) devise_token_auth/confirmations#show
    auth_validate_token GET /auth/validate_token(.:format) devise_token_auth/token_validations#validate_token

    As shown above, /auth includes all the action related to authentication.

    Authenticate

    Let's create a Listing model to show how it works.

    rails g scaffold listing content:text title:string
    

    After migration, add one line code to application_controller.rb

    #application_controller.rb
    class ListingsController < ApplicationController
      before_action :authenticate_user!
      ...
    end
    

    All right, you should get 401 while visit http://localhost:3000/listings/1.

    Sign up

    Firstly, wo don't need users confirm their registration with their own email, so we remove :confirmable in models/user.rb.

    Sending a post requset to http://localhost:3000/auth with the parameters(email, password, password_confirmation) would create a user.

    curl -X POST -H "Cache-Control: no-cache" -H "Postman-Token: 3a9aa5e9-2ba7-7de3-66b4-ec3a85f6ddd0" "http://localhost:3000/auth?email=zhen6939@163.com&password=51190109&password_confirmation=51190109"
    

    Sign in

    According to the routes sheet, implement 'sign in' needs a post request to */auth/sign_in *:

    curl -X POST -H "Cache-Control: no-cache" -H "Postman-Token: 2c7e777b-031d-c958-79e7-04ef75fe9bd5" "http://localhost:3000//auth/sign_in?email=zhen6939@163.com&password=51190109"
    

    It returns access-token, client, expiry, token-type, uid.

    param description
    access-token This serves as the user's password for each request. A hashed version of this value is stored in the database for later comparison. This value should be changed on each request.
    client This enables the use of multiple simultaneous sessions on different clients. (For example, a user may want to be authenticated on both their phone and their laptop at the same time.)
    expiry The date at which the current session will expire. This can be used by clients to invalidate expired tokens without the need for an API request.
    uid A unique value that is used to identify the user. This is necessary because searching the DB for users by their access token will make the API susceptible to timing attacks.

    Using those params properly, we can kindly keep user login at different devices.

    How the authentication works

    As shown above, access-token is used as 'password' for each request. By default, It should be changed after every request to server. At other words, every response of request to server will return different access-token. It means that every request you sent should include access-token which you got at previous request.

    相关文章

      网友评论

      • 飞鸟集:雾草,我只能看作者的名字,谢谢分享
        飞鸟集:哈哈,就是看着有点费力,能力有限,:joy:不然我会认真看完的
        臻有一扑:@飞鸟集 谢谢回复咯~

      本文标题:Rails API With Authentication Si

      本文链接:https://www.haomeiwen.com/subject/iqojlttx.html