OAuth2 Requesting and Storing Token - ruby-on-rails

This is probably a simple question but I can't seem to wrap my head around on how OAuth2 works. So I got upto the point where I can request a token and start pulling data in Ruby console. But after I exit out of Ruby console, I tried requesting data (.rb script) from API again using the same token but it says expired/invalid. Am I suppose to store this token somewhere permanently like in a database or cookie?
Not sure if this matters but when I request a token, it brings me to the OAuth2 page to allow or deny a token request. How do you bypass this in Ruby code? From what I'm reading, you use the token.refresh! method?
Can you please share your insights on what I'm not understanding or missing?

Related

How would you build a production ready authentication system for a GraphQL API built with Rails and React?

I am trying to integrate an authentication system with Graphql and rails that communicates with a React front end and I would like to know what is the best way to do it for a production environment
I know that this might involve using jwt but I would like to know how would you do it?
When the user signs in/up from the react front end it sends the request to the rails graphql api that authenticates the user. Then when the authenticated user makes a request/query it, the backend first makes sure that the user has access to the resources that he is requesting and then send those resources in json to the react front end
This is a bit of an open-ended question. It's probably not really possible to write a specific answer to your question, but here goes nothing.
There are multiple ways to set up authentication with GraphQL. First of all, it's important to understand whether your user is allowed to make any GraphQL queries at all without being authenticated.
You're saying you're authenticating the user with your Rails GraphQL API. Are you doing this with a mutation or with a REST call? If it's just REST and the user isn't allowed to use the GraphQL API without authenticating then you may just be able to block the user from interacting with the GraphQL API at all, when they're not authenticated.
Otherwise it's common to check whether the user is authenticated and if so keep the user data in your GraphQL query context. Then you'll now — per query — whether the user is authenticated.
When the user is attempting to access any resource that they may not be able to see or are attempting to send a mutation without being authenticated, then you can just end the entire query/request with a GraphQL error.
Since GraphQL errors are still considered part of a successful HTTP request you can handle them as usual in your front end as part of the UI. They'll be listed in the usual errors array of the response, as specified in the GraphQL spec.
Regarding JWT, you can of course use JWT to authenticate the user, which requires you to either store a token in a cookie or somewhere else in the user's browser. Typically you'd just send the token in the Authorization header with every GraphQL request.

Obtaining user app_metadata in my resource server using OIDC and Oauth v2.0

I'm struggling to clearly understand the flow of obtaining user app_metadata after an authenticated user sends a request to my Resource Server with an Access Token.
I've seen previous answers on Stack Overflow, but they didn't clarify things enough.
For example, the information I need to obtain is users organizationId (234) and organizationRole (POWER_USER).
Can this information be loaded on the Access-Token? If not, does this mean that my Resource Server has to call the authorization server (Auth0) each time to check these parameters? B/C I see that the ID token isn't being sent with the request.
Is this the best practice? Doesn't this bring a latency toll to call Authorization Server to check these details on each request?
The easiest way to accomplish this (while limiting the amount of requests needed) is to add the data to the token via a custom claim. This can be done in a Rule if you are using auth0, and there is an example on the doc I linked.

Is this a secure method for user authentication? If so, can it be simplified to reduce the total number of requests?

I've been digging around in Koa and had a setup which seemed to work fine. I then decided SSR would be beneficial and I'm struggling a bit with creating a method for authentication which is straightforward.
In essence the steps I am taking are:
User visits Next.JS served page.
User clicks "Login with facebook" and a request is sent to my Koa server at /auth/facebook
OAuth with passport occurs and a token is generated and stored for the user (either created then or updated)
A very short lived token is generated and the user is redirected to the Next.JS application with the short lived token in the URL.
Next.JS sends this short lived token to the Koa API and a real access token is returned and stored in a cookie.
This new access token is used for subsequent requests to the API.
This feels very complicated and I feel it might be possible to remove the short lived token step altogether.
From what I have read, it is not a good idea to use Next.JS for back-end API related logic which is why the auth happens on the Koa-API server and hence the need to pass a short lived token to get a real token.
Am I over-complicating this? Is there a simpler method that I'm just not seeing?
After a bit of fiddling around, I cut it down to only a few requests instead.
I moved Passport.js into a custom Next.JS server (using Koa) and set the callbacks to target Next. Then I verify the token on each request as it is now stored by Next.JS instead of with my API server, cutting out 4 and 5.

Validate JWT token signed with RS256 in Knock (rails)

I am trying to connect React app and Rails app using Auth0. It used to be super simple since tokens were signed with HS256. But since auth.js v8 jwt tokens signed with RS256. I don't have problems with frontend but can't make RoR (I use Knock) work with new signing algorithm. I've added
config.token_signature_algorithm = 'RS256'
and
config.token_public_key = key.public_key
into Knock initializer but still no luck.
Key seems to be correct, at least it works in jwt.io or pure ruby-jwt (at least I was able to read information from token).
I am no expert working with asymmetric algorithms so any help would be appreciated. What I am trying to do right now is to get "access_token" from frontend and to send it in "authorization" header to the backend. I know I need to add "Bearer" into header but is there is any other operation I need to do with token first?
Best, Iurii
Just in case anyone interested here is short discussion on GitHub here is a link

How do I use the oauth gem to validate a token passed into the request?

I am trying to build a service that authenticates users using an oauth 1 signed request. The request includes an oauth token, signature, nonce, and consumer key. The server has access to the corresponding secrets, but it is unclear how to use the oauth gem to validate the token and retrieve the corresponding user. The token was originally generated using the oauth-rails plugin, but the validation needs to take place on a different server from the original rails application (but has access to the same underlying database).
How can I use the oauth gem to accomplish this?
I have looked through the source for the oauth and oauth-plugin gems, but I can't tell where this validation actually happens. Almost all of the documentation I can find refers to using the oauth gem as a consumer, not a provider.
I finally figured out the answer to this, so I'll put it here in the hopes of helping someone in the future.
Once you've retrieved the AccessToken and ClientApplication objects from the underlying database and checked the nonce and timestamp, verifying the signature is as easy as:
signature = OAuth::Signature.verify(request, {}) do |sigblock|
[token.secret, ca.secret]
end
If the signature checks out, signature will be true. Beware - if you're behind an http proxy such as nginx, the SERVER_PORT environment variable may not be correctly set for https requests and you may have to set it manually. If this (or any other seemingly tiny part of the request) is off, it can cause the signature verification to fail even if the request is valid.

Resources