[ROR] JWT를 이용한 회원가입 기능

wooook·2020년 11월 22일
0

이번에 주변 지인분들과 같이 토이프로젝트를 진행하기로 하였고, 제가 맡은 부분은 api 서버 부분이였습니다.

어떤 프레임워크를 써서 구현할지 고민하던중 가장 익숙한 레일즈를 선택하였습니다. 셋팅을 마치고, 회원가입 기능을 개발하면서 사용한 JWT 구현 과정을 글로 써보려고합니다.

1. Gemfile 설치 및 적용

일단 가볍게 Gemfile에 JWT 라이브러리를 적어 줍니다.

gem 'jwt'

그 후 라이브러리를 적용해줍니다.

bundle install

2. Rails에 파일 생성

1) lib/json_web_token.rb 파일을 추가해줍니다.

class JsonWebToken
  SECRET_KEY = Rails.application.secrets.secret_key_base .to_s

  def self.encode(payload)
    payload[:exp] = 15.minutes.from_now.to_i
    JWT.encode(payload, SECRET_KEY)
  end
  
  def self.decode(token)
    decode = JWT.decode(token, SECRET_KEY)[0]
    HashWithIndifferentAccess.new decode
  end
end

encode메소드와 decode메소드를 추가해줍니다.

encode 메소드는 SCERET_KEY와 pay_load를 이용하여 JWT토큰을 생성하기 위해 만든 메서드이고, decode 의경우 유저로 부터 받은 토큰을 해석하기 위해 만든 메소드 입니다.

만약 레일즈가 json_web_token.rb 파일을 불러오지 못 할 경우
confing/application.rb 파일에 아래의 코드를 추가해줘서 lib파일을 모두 불러 올 수 있도록 해줍니다.

config.autoload_paths += Dir["#{config.root}/lib"] 

2) application_controller.rb 파일에 아래와 같이 추가해줍니다.

def token_authentication

    http_request = request.headers["Authorization"]
    auth_token = http_request.to_s.split(" ").last
    decode_token = JsonWebToken.decode(auth_token)
    @user = User.find(decode_token["user_name"])

  rescue JWT::ExpiredSignature => e
    render json: { errors: e}, status: :unauthorized
end

appllcation_controller.rb파일에 token_authentication이라는 메소드를 만들고, 유저로부터 받은 토큰을 해석합니다.

만약 만료 된 토큰일 경우 rescue를 통해서 만료된 토큰이라는 것을 사용자에게 알려줍니다.



3) users_controller.rb 파일에 아래와 같이 추가해줍니다.

  before_action :token_authentication

  def create
    user = User.new(user_params)
    access_token = JsonWebToken.encode(user_name: user.name)
    if user.save
      render json: { access_token: access_token}, status: :ok
    else
      render json: { errors: e}, status: :unauthorized
    end
  end

  private
  def user_params
    params.permit(:email, :password, :name, :nickname, :sns)
  end

저의 경우에는 회원가입을 하는 api를 만드는 중이었습니다. 사용자로부터 받은 값 중 name을 이용하여 JWT 토큰을 생성합니다.

3. 로그인 방식에 개선할 방향은?

위와 같은 경우에는 access_token만을 이용한 방식입니다.

access_token만을 사용할 경우에는 보안적인 위험도 많기 때문에 단독으로는 사용하지 않고, refresh_token과 같이 많이 사용합니다.

그래서 refresh_token을 추가하여 보안적인 측면을 강화해보려고한다.

refresh_token을 추가한 플로우는

  1. 일단 사용자가 로그인을 할 때 access_token과 refresh_token 두개를 발급하고, 사용자에게 전달해준다.

  2. refresh_token의 경우는 서버 db에 저장을 한다.

  3. 사용자가 api를 요청을 할 때마다 access_token을 받아 유효한 토큰인지 확인을 한다.

  4. 만약 aceess_token이 만료 되기 전이라면 refresh_token을 쏘도록 클라이언트에게 요청하고, refresh_token이 유효한 토큰인지 확인한다.

  5. 만약 유효한 토큰이면 사용자에게 정보를 전달해주고, 만료된 토큰일 경우 refresh_token을 비교 하고, 유효한 refresh_token일 경우 access_token을 다시 발급해서 유저에게 전송해준다.

참고: https://kbs4674.tistory.com/89?category=822778

profile
조지아 맥스를 좋아하는 개발자입니다.

0개의 댓글