'Why is session[:user_id] nil in some controller actions but not all?
Junior Developer here. Just when I thought I understood Rails entirely, totally stumped yet again. For the life of me, I cannot figure out why session[:user_id] is nil for some controller actions but not all.
I tried everything, helpers, fixing routes and checking cookie setup etc. I have access to session[user_id]/current_user in my #create method within UsersController, so I should have access to it within the adjacent method inside the same controller right?
Any ruby/rails experts willing to give input? This is my first stack overflow post. Go easy on me if I'm breaking any conventional rules of the site. [My Rails Backend Code][1] [React FrontEnd][2]
UPDATE: I have made great progress with devise so far. Able to sign up and login from my react frontend. However, I can't seem to keep the user logged in. I believe the CSRF token might be resetting after each login or sign up. RAILS BACKEND https://github.com/jasonronalddavis/TextStory REACT FRONTEND https://github.com/jasonronalddavis/TextStory_front_end
RAILS BACKEND sessionsController
def get_current_user
@user = current_api_v1_user
sign_in(@user)
if signed_in?(@user)
render json: UserSerializer.new( @user)
else
render json: {
error: "Not logged in"
}
end
end
REACT FRONETEND src/action/user.js
export const getCurrentUser = () => {
return dispatch => {
return fetch("http://localhost:3001/api/v1/get_current_user", {
credentials: "include",
method: "GET",
headers: {
"Content-Type": "application/json",
'Accept': 'application/json'
},
})
.then(r => r.json())
.then(response => {
if (response.error) {
alert(response.error)
} else {
const stories = response.data.relationships.story_texts.data
dispatch(setUser(response.data))
dispatch(userAttr(response.data))
dispatch(userStories(stories))
}
})
.catch(console.log())
}
}
Solution 1:[1]
If you want to build an authentication system to learn about making wheels you need to separate it from the responsibilites of CRUD'ing users which is something completely different.
In the case of classical cookie based auth system this would typically be called SessionsController:
# Handles user authentication
module API
module V1
class SessionController < ApplicationController
# Sign the user in given a name and password
# POST /api/v1/sessions
def create
user = User.find_by(params[:name])
if user&.authenticate(params[:password])
sign_in(user)
render json: user,
status: :created
else
# always return meaningful HTTP status codes and write your JS
# around it
render json: {error: "invalid name or password"},
status: :not_found
end
end
# Resets the users session by overwriting the session identifier cookie
# DELETE /api/v1/session
def destroy
sign_out
head :no_content # default in later versions of Rails
end
# GET /api/v1/session
def show
render json: current_user
end
private
def sign_in(user)
session[:user_id] = user.id
end
def sign_out
session.delete(:user_id)
end
end
end
end
This is modeled as CRUD but we are actually just modifying the session storage (typically a cookie). Using a middleware based approach to authentication like Warden would be superior though as this allows you mock authentication in your tests and use it thoughout the middleware stack like for example in your routes.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | max |
