create basic backend with login

This commit is contained in:
2026-09-21 21:43:30 +03:00
commit e1c4a5b9ba
79 changed files with 2834 additions and 0 deletions
@@ -0,0 +1,32 @@
class Api::RegistrationsController < ApplicationController
skip_before_action :authenticate_request!, only: [:create]
def create
user = User.new(registration_params)
if user.save
token = JwtService.encode(user_id: user.id)
render json: {
user: user_response(user),
token: token
}, status: :created
else
render json: { errors: user.errors.full_messages }, status: :unprocessable_entity
end
end
private
def registration_params
params.require(:user).permit(:nickname, :password, :avatar)
end
def user_response(user)
{
id: user.id,
nickname: user.nickname,
avatar_url: user.avatar.attached? ? url_for(user.avatar) : nil,
created_at: user.created_at
}
end
end
@@ -0,0 +1,38 @@
class Api::SessionsController < ApplicationController
skip_before_action :authenticate_request!, only: [:create]
def create
user = User.authenticate_by(params.permit(:nickname, :password))
if user
token = JwtService.encode(user_id: user.id)
render json: {
user: user_response(user),
token: token
}
else
render json: { error: "Invalid nickname or password" }, status: :unauthorized
end
end
def destroy
# JWT is stateless; client should discard the token.
# For server-side revocation, implement a token blacklist here.
render json: { message: "Signed out successfully" }
end
def me
render json: { user: user_response(current_user) }
end
private
def user_response(user)
{
id: user.id,
nickname: user.nickname,
avatar_url: user.avatar.attached? ? url_for(user.avatar) : nil,
created_at: user.created_at
}
end
end
@@ -0,0 +1,25 @@
class ApplicationController < ActionController::API
include ActionController::HttpAuthentication::Token::ControllerMethods
before_action :authenticate_request!
attr_reader :current_user
private
def authenticate_request!
token = extract_token
return render json: { error: "Unauthorized" }, status: :unauthorized unless token
decoded = JwtService.decode(token)
@current_user = User.find_by(id: decoded[:user_id]) if decoded
render json: { error: "Unauthorized" }, status: :unauthorized unless @current_user
end
def extract_token
auth_header = request.headers["Authorization"]
return auth_header.split(" ").last if auth_header&.start_with?("Bearer ")
params[:token]
end
end