cbeer / devise-guests

fake 'em until you make 'em
MIT License
130 stars 31 forks source link

How to use it with --api mode? #27

Closed wscourge closed 4 years ago

wscourge commented 4 years ago

It'd be really useful to have some guideline that takes using the gem with rails new project --api mode into consideration.

By default, the API mode disables sessions, and all that's described in How To: Create Guest User that links here is based on the session.

cbeer commented 4 years ago

I'm not sure this gem makes sense in a session-less context and you're probably better off creating and authenticating temporary users through some other mechanism. I'm happy to be persuaded otherwise.

ahaverty commented 3 years ago

@wscourge did you find a good solution to this?

sshaw commented 2 years ago

I'm not sure this gem makes sense in a session-less context and you're probably better off creating and authenticating temporary users through some other mechanism.

Devise mostly supports API apps. There is also https://github.com/waiting-for-dev/devise-jwt. Seems to make sense for this to support API apps using Devise or Devise + Devise JWT.

sshaw commented 2 years ago

Seems to make sense for this to support API apps using Devise or Devise + Devise JWT.

Just had a quick looksy into this so figured I'd leave an important note:

Devise JWT (really Warden JWT) requires one set the method/paths to issue the bearer token on: https://github.com/waiting-for-dev/devise-jwt#dispatch_requests

If you have a guest users, you want this on many paths. The problem is this setting will output a bearer token every time the method/path match, even if a token was set on the incoming request. So, if you want to use JWT, it appears you'd have to set the token manually. Something like this (untested):

def authenticate_user_or_create_guest
  return if current_user

  user = created_guest_user
  # set Devise current_user
  sign_in :user, user

  # Add the JWT token for user
  add_token_to_env(user, request.env)
end

def add_token_to_env(user, env)
  aud = Warden::JWTAuth::EnvHelper.aud_header(env)
  token, payload = Warden::JWTAuth::UserEncoder.new.call(user, nil, aud)
  user.on_jwt_dispatch(token, payload) if user.respond_to?(:on_jwt_dispatch)
  env[Warden::JWTAuth::Hooks::PREPARED_TOKEN_ENV_KEY] = token
end