class Api::V1::PasswordsController
User controller
Public Instance Methods
reset_password_instructions()
click to toggle source
Password Reset Flow
-
User requests password reset instructions by sending params with email
to /api/v1/passwords/reset
# File lib/generators/jwt_api/templates/api/v1/passwords_controller.rb, line 10 def reset_password_instructions @user = User.find_by(email: password_params[:email]) if @user.nil? render json: { message: 'email not found' }, status: :not_found else @user.reset_password_token = SecureRandom.uuid @user.reset_password_sent_at = Time.now if @user.save JwtMailer.reset_password(@user.id, @user.reset_password_token).deliver render json: { message: 'reset password instructions sent' }, status: :ok else render json: { message: @user.errors }, status: :not_found end end end
update_password()
click to toggle source
Step 3: User submits password reset form with new password and includes the newly issued Bearer token within 10 minutes of issuing the token
# File lib/generators/jwt_api/templates/api/v1/passwords_controller.rb, line 55 def update_password if user_found? && passwords_match?(password_params[:password], password_params[:password_confirmation]) password_update(password_params[:password]) end end
verify()
click to toggle source
Step 2: User clicks on link in email which sends them to /api/v1/passwords/verify with a token in the params, if a succesful response is received, the client can store the newly issued JWT and redirect the user to the password reset form
# File lib/generators/jwt_api/templates/api/v1/passwords_controller.rb, line 29 def verify @user = User.where(reset_password_token: params[:token]).first if @user.nil? render json: { message: 'reset password token not found' }, status: :not_found elsif @user.reset_password_sent_at < 1.hour.ago render json: { message: 'reset password token has expired' }, status: :not_found else @user.reset_password_token = nil @user.reset_password_sent_at = nil @user.jti = SecureRandom.uuid @user.save iat = Time.now.to_i exp = Time.now.to_i + 10 * 60 render json: { token: JsonWebToken.encode({ user_id: @user.id, jti: @user.jti, iat: iat, exp: exp }) }, status: :ok end end
Private Instance Methods
password_params()
click to toggle source
# File lib/generators/jwt_api/templates/api/v1/passwords_controller.rb, line 87 def password_params params.require(:user).permit(:email, :password, :password_confirmation, :reset_password_token) end
password_update(password)
click to toggle source
# File lib/generators/jwt_api/templates/api/v1/passwords_controller.rb, line 79 def password_update(password) if @user.update(password: password, jti: SecureRandom.uuid) render json: { message: 'password updated, please reauthenticate' }, status: :ok else render json: @user.errors, status: :unprocessable_entity end end
passwords_match?(password, password_confirmation)
click to toggle source
# File lib/generators/jwt_api/templates/api/v1/passwords_controller.rb, line 73 def passwords_match?(password, password_confirmation) return false if password.nil? || (password != password_confirmation) true end
user_found?()
click to toggle source
# File lib/generators/jwt_api/templates/api/v1/passwords_controller.rb, line 65 def user_found? @user = User.find(auth_token[:user_id]) rescue JWT::VerificationError, JWT::DecodeError render json: { errors: ['Unauthorized'] }, status: :unauthorized true end