OAuth Refresh Token Best Practice [closed] - api

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I am implementing OAuth for a project, and I want to know the best way to handle refresh tokens.
The API I call will return a JSON object with access_token, expires_in, and refresh_token.
So I was wondering, is it better to:
Calculate the time when the access_token will expire, store that in the database. Check that the access_token is not expired every time I make an API call, and if it is expired then use the refresh_token to get a new access_token.
(Additional Question: how do I make sure that the time which I calculate for the token expiration is accurate? Because the expire_in value probably starts from when the API server generated the key, and not when I receive it.)
OR
Just try to make the API call with the access_token every time, and if that returns with an error then use the refresh_token.
I am also open to other options of implementing this.

The client should always be prepared to handle an error returned from the API that indicates that the access_token validation failed. Depending on the implementation the access token may have been revoked or declared invalid otherwise.
The client may then use a refresh_token to get a new access token and try again. So you can choose to implement 1. but it does not free you from implementing 2. as well, so you may choose to stick to only implementing 2 and minimize the amount of code required.
Of course if you want to prevent errors from happening as much as possible you could implement 1. to optimize the number of calls and reduce the number of errors in the whole process.

This article explains practices by some big cloud services:
http://blog.cloud-elements.com/oauth-2-0-access-refresh-token-guide
However, IMO, the refresh token should have an expiration time, say 1 year. It should change when a new access token is issued using the refresh token, however, the expiry date should remains the same. When you need a refresh token forever, just issue the refresh token with max date value. Also, make sure to mark the old access and refresh tokens as deleted when issuing the new refresh token.

Related

Authorization best practices? Where should authorization take place to hide/block pages from the user in nextjs? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 days ago.
Improve this question
I am currently in the process of designing a network of servers and databases for a project.
One key aspect of this project is the implementation of a central authentication server which will utilize session IDs to track sessions. These session IDs will be stored in cookies and sent back to users upon successful login.
Note: I understand that nextjs can work as both a front end and a back end. For reasons I will not get into here, nextjs is being used as a front end, and a separate central authentication server is being used for authentication. There are other servers/databases that will store data that users can access if they have proper permissions levels.
In step 1, I have no questions.
In steps 2 and 3, when the cookie is sent back to the nextjs server, what is the best practice for nextjs to determine the authorization level of the user?
I believe it's important that...
- Nextjs should know what navigation tabs to show, etc., when it renders the page for the user.
- Nextjs should also know what pages the user is allowed to visit. If the user is asking for a server-side rendered page that it isn't allowed to visit, it should be blocked
Possible option: Here, do I include some sort of JWT with authorization levels? It is my understanding that nextjs may be able to read these JWT authorization levels in middleware, then deny certain page requests that the user has by reading the JWT each time they request a page. Perhaps, even without middleware, functions could be used within the pages that would run server-sided, checking the JWT permission levels. Note that, in order for the nextjs server to know what the authentication levels are for the user, the tokens would have to be created in the central auth server, and then sent to the nextjs server.
Side thought: It seems that if I were to implement a function that checks the authorization level on a SPA, there would always be a way that a hacker could at least visit the blank page, correct? In other words, the only way to truly hide pages and navigation tabs from a hacker would be by somehow checking authorization levels server side (server-sided rendering), and then sending back a rendering of the page that only shows items related to the exact permissions of the user?
Overall, I would greatly appreciate any advice or insight on the best methods for authorizing users and limiting access to pages and tabs based on permission levels. While cookies will be used to store the session id and determine the data that users can receive when making API calls, additional measures such as JWT may be necessary for authorizing users to view specific pages. Is it common to utilize a combination of session/cookies and JWT for this purpose? What are the recommended best practices in this scenario?
Thank you for your assistance.

Building an API to send random numbers to my website [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 months ago.
Improve this question
I am trying to make a custom API which uploads random numbers generated to my website page (to learn how API works). And whenever I want to see the page, I use my API key to do so. Can you help me in this? I am new to API stuff.
When creating APIs, there are lots of decisions to make. You could render your structure on the client-side and query your application server via RESTful API calls. Or you could have a server-side rendering approach and use your API internally. There are four main types of APIs:
Partner
Internal
Composite
REST
https://www.techtarget.com/searchapparchitecture/tip/What-are-the-types-of-APIs-and-their-differences
In your scenario it seems that you need to either choose an internal API approach or a RESTful approach.
Your random number function itself would be similar in both cases (a simple function written in the language of your choice).
However, the token usage largely depends on the type of your API.
You need to decide whether you are going to have usernames and passwords and is the purpose of your token only to avoid frequently logging in with very sensitive data, such as username and password, so, you use a token instead, which, if falls into the wrong hands, then they could not steal the identity of your users for good, as they are still not reaching these credentials. If so, then you will need to generate the token periodically. A way to do so is to generate it every week/month (whatever) and somehow send it out to your users. Or it could be generated whenever the user has to log in, sent to the user, who will be able to use that token from there on.
Or, you could separate the token from the login and provide a UI for the user where he/she can generate tokens while being logged in. There are quite many ways to approach this.
Otherwise, if there is no username and password and, there is a token and secret to identify the user, then you will need an alternative to the login. It could be a simple request for token generation. Or it could be a repeatedly generated and sent token.
In any measures, when you intend to run an API function as a user, then you will need to send the information that identifies your user. On most webpages this is handled by getting a session ID (that acts as a token) upon login and then, while the session exists, that session ID is always sent to the webpage, whatever request is being sent, this is how the website knows that you are logged in. Most webservers and programming languages that handle web requests also handle token generation and usage and browsers are in line with these through the cookies, which are small files that contain information for the website.
If you are having a custom environment or you prefer a custom token management, then of course you can implement your own.
But, if you want to achieve simplicity, then you could implement a register and a login feature for your API as well as the number randomizer, so these are 3 API functions for now, call the register when a user registers, store a 1-way-encrypted password, do a validation (like email sending with a token to the user) and implement token-based user validation, which is a fourth API function. So, the user:
registers
receives an email with a token
clicks on a link that has that token as a request parameter
once that page opens, store the user as an authenticated user and remove the registration token
This will enable logging in for your user. Once your user is logged in, a session ID should be generated (in PHP you need to look into the functions whose name start with session_, for example) and then using that session ID your API should make sure that the randomizer can be called and your UI should be designed in such a way that this feature could be found by users.
If I may, I advise you to avoid getting into your own token generation while you are learning, choose the simplest ways and once the simplistic configuration you have chosen is working reliably, then you may choose to write your own token logic if you prefer that for some reason.

Google API Refresh Token Expiring [duplicate]

This question already has answers here:
How to fix Google API 'invalid_grant' error
(2 answers)
Closed 12 months ago.
I read here that A Google Cloud Platform project with an OAuth consent screen configured for an external user type and a publishing status of "Testing" is issued a refresh token expiring in 7 days. Does this mean that despite calling the refresh function from within Python, one must manually relogin every 7 days? Am I interpreting this correctly? Or is it possible to automate this such that a new Refresh token is issued for 7 more days all within the code?
I am making this project just for myself, so I see no reason to publish it (I want to keep it in testing), but I need the credentials to never expire (so that my intervention is never required after I generate the first token). Any help is appreciated!
Yes you understand well, so the token expires after 7 days, but pay attention, only in "testing" mode. This mean that you could switch your app in "production" mode and the token won't expired.
But take a look also to another detail, even if in production you will 50 token per your Client user (client-user). Not client_id. This is mean that, for every person that log in your application you can have all of them authenticated max 50 times. Each Refresh token you receive will work. After the 50th the oldest one will stop working. On the other hand the token will works for up to 6 months I think, if it hasn't been used for 6 months it will be invalidated.
So there isn't a way to have a lifetime token, and, for security reason, is a correct approach, by the way Google itself provide an antipattetn that you can use to set a long life token, for info read google long expiration token

Keycloak: Refresh Token Automatic Reuse Detection [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 12 months ago.
This post was edited and submitted for review 12 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
We are using Keycloak for authentication (OIDC):
the user input his Username/Password and enter the Frontend Browser page (Client)
Rest API calls to the Backend (Server) has the Bearer Token (= access token) in the Header
calls are queued in RabbitMq
after a long running task the stored Bearer token from the next running task is already expired and has to be renewed by a Refresh Token
Now the scenario: someone is able to steal the Refresh Token and get always new valid access tokens. Keycloak should recognize this by "Automatic Reuse Detection" and requires re-authentication to prevent this!
We tried this out in Postman and were able to use the same Refresh Token on both sides (different Clients in the same Network) several times without any problems.
An other possibility would be to use Revoke Refresh Token to ON and Refresh Token Max Reuse to 0. But then it is not ensured that the valid user is still able to authenticate because of race condition with malicious users:
The Attacker uses the Refresh Token before the valid user
the Refresh Token becoming invalid for the valid user due Revoke Refresh Token
What are the best practicies here? Any kind of help is very appreciated!

REST API design - querying mail data - which poison to choose? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
we are currently designing an internal REST api. we have the following use case:
a user (109) wants to read a message that he has sent to another user (110)
the reading user (109) is known to the app through his token credentials that he received after authenticating (while doing the GET request)
we assume in this example the user 109 was the sender and 110 the receiver
to summarize from the users perspective "give me the mail that i (109) have sent to 110"
the following URIs came to our mind but we can't decide which one to take:
a) GET http://localhost:9099/api/mails/109?receiverUserId=110
b) GET http://localhost:9099/api/mails?senderUserId=109&receiverUserId=110
c) GET http://localhost:9099/api/mails?receiverUserId=110
d) GET http://localhost:9099/api/mails/me/to/110 (when logged in as 109 via token credentials we know that "me" is 109)
f) GET http://localhost:9099/api/mails/109/to/110 (explicit request, e.g. for admins … has to be guarded against illegal access)
all the links are "context sensitive" that is sending one of the links to the receiver (110) will yield different results executing the GET request.
i would like to know your opinion on what url to use.
any help highly appreciated.
cheers
marcel
Different responses to different clients, for same URL is okay.
StackExchange does it:
GET /me/comments/{toid}
which is documented here.
Twitter does it too:
GET /statuses/home_timeline
which is documented here.
Both of those URLs infer the logged in user based on authentication. Yes, it defeats caching if users share a cache, but IMO, this is okay. Whether or not this breaks the 'resource identification' constraint of REST is probably debatable. The answer to this question, and a subsequent comment there shows to me why it is debatable.
In fact, among the options, you do mention URLs which are not 'context sensitive':
GET /api/mails?senderUserId=109&receiverUserId=110
This one will always return messages from 109 to 110. But while one client would want to see this result when viewing 'sent' messages, the other would want to see this result when viewing 'received' messages. Kind of weird eh? Plus, on the server you'll have to check that the authenticated user is 109|110, else throw a 401 UNAUTHORIZED.
I would go with something like:
GET /mail/sent
returns all sent mail. And:
GET /mail/sent?to=110 (like applying a 'filter' to /mail/sent)
OR
GET /mail/sent/110 (clean URL)
returns mail sent to 110.
"Context sensitive" links are bad idea for a REST API (in particular, this hinders caching). If you want to just use HTTP this is OK.
So I would suggest using URLs that do not depend on current user and limit access to them according to your rules.
In my opinion, you need 2 layers:
One is the internal layer, which doesn't require user authentication, it's only accessible from internal components. It includes APIs like
GET http://localhost:9099/api/mails?senderUserId=109&receiverUserId=110
The advantage of this layer is the testability, reusability and cachability.
The other layer is the external layer, which requires user authentication and is accessible from external clients. It includes APIs like
GET http://localhost:9099/api/mails?receiverUserId=110.
Clients must login to get the token credentials, then server can get the user info from this token, and map the external API call to internal API call.
You may have different kinds of authentication methods, but the internal layer will not be changed, you just need to map different external layers to the internal layer.