LoginSignup
25
26

More than 5 years have passed since last update.

Devise for mobile

Last updated at Posted at 2012-04-18

皆さん、WebとMobileの認証、どのようになってるんだろうなぁとよく思う今日この頃。DeviseとMobileの共存について調べたのでメモ。もっといい方法あったら教えて欲しいです。

Precondition

下記のようにして、UserというModelがdeviseを用いて作られている前提です。

rails generate devise User

あと、こちらを参考にしてます。

さて

全体の流れとしては

  • Mobile用TokenカラムをUserテーブルに追加
  • Mobile用Tokenを制御するControllerの作成

では

まず、Mobile用Tokenカラムを作成します。db/migrate/のなかに適当なmigrateファイルを作成。僕の場合は20120418141059_add_devise_columns_to_user.rbとしました。中身はこんな感じ

class AddDeviseColumnsToUser < ActiveRecord::Migration
  def self.up
    change_table :users do |t|
      t.token_authenticatable
    end
  end
  def self.down
    t.remove :authentication_token
  end
end

そうそう、忘れぬうちに/app/model/user.rbbefore_filter:token_authenticatableを追加しておく。

んで、rake db:migrateを実行。
次にTokenを制御するControllerを作成します。

rails g controller api/v1/tokens

そしたら、config/route.rbを編集。

namespace :api do
  namespace :v1  do 
    resources :tokens,:only => [:create, :destroy]  
  end
end

はい、それではControllerの中身を書きます。下記の通り

class Api::V1::TokensController  < ApplicationController 
  skip_before_filter :verify_authenticity_token
  respond_to :json

  def create
    email = params[:email]
    password = params[:password]

    if request.format != :json
        render :status=>406, :json=>{:message=>"The request must be json"}
        return
    end

    if email.nil? or password.nil? 
      render :status=>400, :json=>{:message=>"The request must contain the user email and password."}
      return
    end

    @user=User.find_by_email(email.downcase)

    if @user.nil?
      logger.info("User #{email} failed signin, user cannot be found.")
      render :status=>401, :json=>{:message=>"Invalid email or passoword."}
      return
    end

    @user.ensure_authentication_token
    @user.save!

    if not @user.valid_password?(password) 
      logger.info("User #{email} failed signin, password \"#{password}\" is invalid")
      render :status=>401, :json=>{:message=>"Invalid email or passoword."} 
    else
      render :status=>200, :json=>{:token=>@user.authentication_token} 
    end
  end

  def destroy
    @user=User.find_by_authentication_token(params[:id])
    if @user.nil?
      logger.info("Token not found.")
      render :status=>404, :json=>{:message=>"Invalid token."}
    else
      @user.reset_authentication_token!
      render :status=>200, :json=>{:token=>params[:id]}
    end
  end  
end  

これで実装は終了!あとはアクセス!

http://localhost:3000/api/v1/tokens.jsonにPOSTでアクセス!Chromeのエクステンション「Simple REST Client」等でテストすると便利です。忘れていけないのがHeaderに

Content-type : application/x-www-form-urlencoded

を加えること。引数は

email=wirte_email_address_here&passowrd=write_passowrd_here

な感じになります。

Reference

25
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
26