11 Authentication
- def: verify the identity of a user
Step 1: User Model¶
-
built-in feature
has_secure_passwordto securely hash and store passwords- To use it - have
bcryptgem in your Gemfile
- To use it - have
-
Gemfile: - User model:
- This adds methods to set and authenticate against a BCrypt password. This requires a
password_digestattribute in your database.
Step 2: User Registration¶
-
Create a form for users to register. You'll need a UsersController and corresponding views.
-
In
users_controller.rb, add acreateaction: - The form for registration (
new.html.erb) should include fields for email, password, and password_confirmation.
User Controller¶
- To manage user-related actions
- Acts as an intermediary between user models and views
User Management Actions¶
- New: Displays a form for creating a new user. This is usually the registration form where new users can sign up by providing their details.
- Create: Handles the form submission for creating a new user. It takes the input from the "new" form, creates a new User record in the database, and handles success or failure scenarios such as showing validation errors or redirecting to a new page upon successful creation.
- Edit: Displays a form for editing an existing user's details. This action is typically protected to ensure that only the user in question (or an administrator) can edit a user's details.
- Update: Handles the form submission for updating a user's details. Similar to the "create" action, it takes input from the "edit" form, updates the User record in the database, and handles success or failure scenarios.
def update if @user.update(user_params) flash[:notice] = "Successfully updated #{@user.proper_name}." redirect_to users_url # maps to the index action of the UsersController # showing a list of users or a similar page else render action: 'edit' # renders the 'edit' action's view template again # allows the user to see the form with the previously submitted values # still filled in, along with any validation error messages that were # generated during the update attempt end end -
Show: Displays a single user's details. This action is used to show a user's profile page, which might include their name, email, and other personal details.
-
Index: (Optionally) Lists all users. Depending on the application's requirements, this action might be used to display a list of all users, often used in administrative interfaces.
- Destroy: (Optionally) Deletes a user. This action allows for the removal of a user from the database, typically restricted to the user themselves or an administrator.
Step 3: Sessions Controller¶
-
Generate a Sessions controller for handling login and logout:
-
In
sessions_controller.rb, add actions for creating (login) and destroying (logout) sessions:def create user = User.authenticate(params[:username], params[:password]) if user session[:user_id] = user.id redirect_to home_path, notice: "Logged in!" else flash.now.alert = "Username and/or password is invalid" render "new" end end def destroy session[:user_id] = nil redirect_to home_path, notice: "Logged out!" end -
The login form (
app/views/sessions/new.html.erb) should have fields for email and password, and submit to thecreateaction inSessionsController. -
You'll need to set up a way to keep track of the current user's login state. This usually involves setting a session variable when the user logs in and clearing it when the user logs out.
- In
sessions_controller.rb, when logging in:session[:user_id] = user.id - And when logging out:
session.delete(:user_id)
- In
Step 4: Access Control¶
-
set up before actions in your controllers to restrict access to logged-in users:
-
before_action: callback method run before other actions in the controller are executed. only: [:show, :edit, :update, :destroy]specifies that theset_usermethod should only be run before theshow,edit,update, anddestroyactions. This means that before any of these actions are performed, Rails will first execute theset_usermethod.before_action :check_login: a security measure to ensure that certain actions can only be performed by authenticated users
Summary¶
- User Model
has_secure_password--bcryptGem +password_digestattr. in db
- Users Controller
- Usage: create form for users to REGISTER
- Actions: new, create, edit, update, show, index, destroy
- access control
- Sessions Controller
- Usage: handle LOGIN / LOGOUT
- Actions: create, destroy
Authentication vs. Authorization¶
- authentication
- verifying who a user is
- Rails has built-in methods (
has_secure_passwordmethod in models, which works in conjunction with thebcryptgem to securely hash and store passwords)
- authorization
- determining what an authenticated user is allowed to do
- about permissions and roles: deciding which parts of the application a user can access and what actions they can perform
- Tools like CanCanCan in Rails help manage these permissions elegantly
Routing to the Sessions Controller¶
- User visits
localhost:3000/login - Dispatcher looking at
routes.rbfile - Rails routes the request to Sessions controller's
newaction, via the line:get login, to: 'sessions#new', as: :login
- Summary: dispatch requests for
/loginto thenewaction in theSessionsController, which typically renders a login form.
Sessions and State¶
HTTP is inherently stateless, meaning it doesn't remember previous interactions. Sessions are a way to overcome this limitation by preserving state across requests. When a user logs in, a session is created to store their information, which can be held:
- In the database
- In memory
- On a specific server
The session is represented in Rails as a session hash, which persists for the duration of the user's visit to the website. Additionally, Rails uses:
- An
errorhash to store information about validations that failed. - A
paramshash to hold parameters received from forms or the URL. - 有一个session database
Sessions Controller¶
- handling the login and logout
-
doesn't require sessions model
-
createmethod - log in- authenticate user: check user's credentials
- create a new session (if correct)
- redirect to home page (so no view template for create action)
get 'home', to: 'home#index', as: :home- home_path 这个shortcut是在route里面定义的 用as: :home
- generally speaking, 所有主要功能是redirect的action都没有view templates 比如create,update,destroy
Application Controller and Current User¶
application_controller.rbdefinescurrent_usermethod- determine the currently logged-in user across the application
- checks the session to find the user's ID and then retrieves the user's information from the database.
- helper method for both authentication and authorization 根据role来决定干什么