2017-11-09 14 views
0

私はユーザーがログインする必要があり、特定のページに上陸する必要があります。レールでIDを暗号化および復号化する方法は?

基本的に、ユーザーは電子メールでリンクを取得し、そのリンクをクリックすると、システムにログインして特定のページに移動します。現在、レコードID(ユーザーID)を使用してこの機能を実装しています。

URLは次のようになります。

localhost:3000/details?user_id=412 

def details 
    @user = User.find(user_id) 
    signin(@user) 
end 

上記のURLのため、誰でもIDを変更して他のユーザーアカウントにランダムにアクセスできます。私は、このIDをURLで暗号化し、コントローラのアクションで私はそれを復号化したい。私は、このアクションだけを実装したいアプリケーションからこの暗号化を欲しません。例えば

localhost:3000/details?user_id=SnrIcaMA8rikrnNX6RRKNw 

def details 
    @user = User.find(decrypt(user_id)) 
    signin(@user) 
end 

答えて

1

ここに任意の暗号化を伴わする必要はありません。

最も簡単な解決策は、ユーザーテーブルに新しいフィールドを追加することです(email_token(または何か))。それに任意のランダム値を設定します。 SecureRandom.hexまたはSecureRandom.uuidが良い例です。

次に、このトークンを使用して、ユーザーIDではなくリンクを生成します。あなたのリンクは次のようになります。

example.com/details?token=d3fff15f2e1707719a2acbd4c1edd110 

そして、あなたのコントローラであなたは別の既存のトークンを推測しようとしている幸運

user = User.where(email_token: params[:token]).first 
if user 
    # show page 
else 
    # redirect to "not authorized" page 
end 

ような何かを行います。

ユーザーIDからい​​くつかの価値を引き出すことの利点の1つは、リンクまたはトークンがフォーラムなどに投稿された場​​合、他のユーザーに影響を与えることなく、侵害されたトークンを変更することです。

1

Rails 5がhas_secure_tokenを導入しました。これはhas_secure_passwordのように、車輪を再改造する必要性を取り除くことでセキュリティを向上させることを意図しています。これはSergio Tulentsevの優れた答えのようなトークンを使用しますが、トークンはSecureRandom.base58によって生成されます。

# Schema: User(token:string, auth_token:string) 
class User < ActiveRecord::Base 
    has_secure_token 
    has_secure_token :auth_token 
end 

user = User.new 
user.save 
user.token # => "pX27zsMN2ViQKta1bGfLmVJE" 
user.auth_token # => "77TMHrHJFvFDwodq8w7Ev2m7" 
user.regenerate_token # => true 
user.regenerate_auth_token # => true 

使用できるトークンに基づいてユーザー認証を行うには:あなたが考案またはちょうどウォーデンを使用している場合は、トークンauthentication strategyを作成することができます

@user = User.find_by!(token: params[:token]) 

を。

module Devise 
    module Strategies 
    class Token < Base 
     def valid? 
     params['token'] 
     end 
     def authenticate! 
     u = User.find_by(token: params[:token]) 
     if u 
      fail!("Invalid token") 
     else 
      success!(u) 
     end 
     end 
    end 
    end 
end 
0

必要なものはかなり簡単です。あなたはこの音をもっと複雑にしています。

これは2つの方法で実現できます。私は実際に私のアプリで両方を使用します。

  1. UUID。 /user/1の代わりに/user/560a56b2-627b-4c28-a685-8d18674060cbを使用してください。SecureRandom.uuid
  2. を使用してUUIDを生成できます。所有権を確認してください。これは、ユーザー認証にDeviseを使用する私のアプリで使用している実際のコードです。

user_controller

before_action :check_ownership 

def check_ownership 
    redirect_to authenticated_root_path and return unless user == current_user || current_user.try(:admin) 
end 

コードはかなり自明です。 ID 1のcurrent_useruser/2にアクセスしようとすると、root_pathにリダイレクトされます。ユーザーがadminの場合、彼には表示されますuser/2

+0

これは誤ったUUIDの使用であり、あくまでもセキュリティで保護されていると言います。 UUIDは、dbの複製に関するいくつかの問題を解決する数値IDの代替手段です。彼が使用しなければならないのは、IDと改ざん可能なトークンです。 – max

関連する問題