Rails에서 고유 한 토큰을 만드는 가장 좋은 방법은?
여기 내가 사용하는 것이 있습니다. 토큰은 반드시 추측 할 필요는 없으며 다른 것보다 짧은 URL 식별자와 비슷하며 짧게 유지하고 싶습니다. 온라인에서 찾은 몇 가지 예를 따랐으며 충돌이 발생하면 아래 코드가 토큰을 다시 만들 것이라고 생각 하지만 확실하지 않습니다. 그래도 가장자리가 조금 거칠어지기 때문에 더 나은 제안이 궁금합니다.
def self.create_token
random_number = SecureRandom.hex(3)
"1X#{random_number}"
while Tracker.find_by_token("1X#{random_number}") != nil
random_number = SecureRandom.hex(3)
"1X#{random_number}"
end
"1X#{random_number}"
end
토큰에 대한 내 데이터베이스 열은 고유 인덱스이며 validates_uniqueness_of :token
모델 에서도 사용 하고 있지만 앱에서 사용자의 작업 (주문을하고 토큰을 본질적으로 구매)에 따라 자동으로 배치로 생성되기 때문에 앱에 오류가 발생하는 것은 불가능합니다.
충돌 가능성을 줄이고 마지막에 다른 문자열을 추가하거나 시간 또는 그와 같은 것을 기반으로 생성 된 문자열을 추가 할 수는 있지만 토큰이 너무 오래 걸리는 것을 원하지 않습니다.
-업데이트-
2015 년 1 월 9 일 현재이 솔루션은 Rails 5 ActiveRecord의 보안 토큰 구현으로 구현되었습니다 .
-레일 4 & 3-
나중에 참조 할 수 있도록 안전한 임의 토큰을 만들고 모델의 고유성을 보장하십시오 (Ruby 1.9 및 ActiveRecord 사용시).
class ModelName < ActiveRecord::Base
before_create :generate_token
protected
def generate_token
self.token = loop do
random_token = SecureRandom.urlsafe_base64(nil, false)
break random_token unless ModelName.exists?(token: random_token)
end
end
end
편집하다:
@kain 제안, 나는 대체, 합의 begin...end..while
와 loop do...break unless...end
이전의 구현이 미래에서 제거 얻을 수 있기 때문에이 대답.
편집 2 :
Rails 4 및 우려 사항을 고려하여이를 우려 사항으로 옮기는 것이 좋습니다.
# app/models/model_name.rb
class ModelName < ActiveRecord::Base
include Tokenable
end
# app/models/concerns/tokenable.rb
module Tokenable
extend ActiveSupport::Concern
included do
before_create :generate_token
end
protected
def generate_token
self.token = loop do
random_token = SecureRandom.urlsafe_base64(nil, false)
break random_token unless self.class.exists?(token: random_token)
end
end
end
Ryan Bates uses a nice little bit of code in his Railscast on beta invitations. This produces a 40 character alphanumeric string.
Digest::SHA1.hexdigest([Time.now, rand].join)
There are some pretty slick ways of doing this demonstrated in this article:
My favorite listed is this:
rand(36**8).to_s(36)
=> "uur0cj2h"
This might be a late response but in order to avoid using a loop you can also call the method recursively. It looks and feels slightly cleaner to me.
class ModelName < ActiveRecord::Base
before_create :generate_token
protected
def generate_token
self.token = SecureRandom.urlsafe_base64
generate_token if ModelName.exists?(token: self.token)
end
end
If you want something that will be unique you can use something like this:
string = (Digest::MD5.hexdigest "#{ActiveSupport::SecureRandom.hex(10)}-#{DateTime.now.to_s}")
however this will generate string of 32 characters.
There is however other way:
require 'base64'
def after_create
update_attributes!(:token => Base64::encode64(id.to_s))
end
for example for id like 10000, generated token would be like "MTAwMDA=" (and you can easily decode it for id, just make
Base64::decode64(string)
This may be helpful :
SecureRandom.base64(15).tr('+/=', '0aZ')
If you want to remove any special character than put in first argument '+/=' and any character put in second argument '0aZ' and 15 is the length here .
And if you want to remove the extra spaces and new line character than add the things like :
SecureRandom.base64(15).tr('+/=', '0aZ').strip.delete("\n")
Hope this will help to anybody.
Try this way:
As of Ruby 1.9, uuid generation is built-in. Use the SecureRandom.uuid
function.
Generating Guids in Ruby
This was helpful for me
you can user has_secure_token https://github.com/robertomiranda/has_secure_token
is really simple to use
class User
has_secure_token :token1, :token2
end
user = User.create
user.token1 => "44539a6a59835a4ee9d7b112b48cd76e"
user.token2 => "226dd46af6be78953bde1641622497a8"
To create a proper, mysql, varchar 32 GUID
SecureRandom.uuid.gsub('-','').upcase
def generate_token
self.token = Digest::SHA1.hexdigest("--#{ BCrypt::Engine.generate_salt }--")
end
I think token should be handled just like password. As such, they should be encrypted in DB.
I'n doing something like this to generate a unique new token for a model:
key = ActiveSupport::KeyGenerator
.new(Devise.secret_key)
.generate_key("put some random or the name of the key")
loop do
raw = SecureRandom.urlsafe_base64(nil, false)
enc = OpenSSL::HMAC.hexdigest('SHA256', key, raw)
break [raw, enc] unless Model.exist?(token: enc)
end
참고URL : https://stackoverflow.com/questions/6021372/best-way-to-create-unique-token-in-rails
'development' 카테고리의 다른 글
펠리칸 3.3 pelican-quickstart 오류“ValueError : unknown locale : UTF-8” (0) | 2020.06.08 |
---|---|
리눅스 터미널에서 두 파일 비교 (0) | 2020.06.08 |
UITapGestureRecognizer-단일 탭 및 이중 탭 (0) | 2020.06.08 |
문자열 배열을 ArrayList로 변환 (0) | 2020.06.08 |
iOS Swift 앱의 배경보기에 그라디언트를 적용하는 방법 (0) | 2020.06.08 |