How to verify in AWS Cognito amplify if idToken and accessToken and refreshToken are valid? - amazon-cognito

Currently I trying to verify if a refreshToken is still valid after revoke it using the boto3 method. Any suggestion about how to do this?
I revoking the refresh token as follows:
def revoke_refresh_token(refresh_token):
import boto3
print(f"REVOKING TOKEN -> {refresh_token}")
client = boto3.client('cognito-idp')
client.revoke_token(
Token=refresh_token,
ClientId='MY_CLIENT_ID',
)
print("TOKEN REVOKED")
return "TOKEN REVOKED"

You can validate refresh tokens as you would with any other JWT token, by validating the JWT's structure, the signature and the claims. See this document for help on how to do that Cognito tokens: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html.
When it comes to checking if tokens have been revoked, I believe that you'll just need to build your app to handle tokens being revoked and redirect the user to sign-in when this happens. I am not aware of anyway you can currently validate refresh tokens, other than to perhaps attempt to generate new access/id tokens and see if you are rejected.

Related

How to use JWT Authentication with Django for logout?

I have used DRF and simple JWT for the user application and I have tryied make my logout for an application on DRF, but I know how to delete authentication token, I have the blacklist token but the token continues to serve
I want to delete the authentication token, because the refresh-token is in the blacklist token now
You need to put this setting in settings.py or locally applied at views.py like this
this setting is for if you applied globally JWT Auth
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}

Use JSON Web Token and Firestore support for Bearer token

I want to have authentication and authorization support in Firestore while using a node.js app that talks to Firestore. Users interact via a URL (http.get with embedded tokens) and that interacts with a node.js app. The app accepts some input from user, then talks to firestore. The access token needed for the client to perform secure activities are all embedded in the GET url (the id + access token).
I have a flow here, and want to validate if this flow is right or I am missing something? I am unable to find the most definite document that can guide me on the steps to follow.
First off I generate JWT token part before generating the GET url:
The function used to generate the JWT token is as follows:
// generate JWT token
function getJWT() {
var token = jwt.sign({
exp: Math.floor(Date.now() / 1000) + (60 * 60) * constants.JWT_TOKEN_VALIDITY_HOURS,
admin: '​XXXXXXX'
}, constants.JWT_SECRET_TOKEN);
return token;
}
Bearer Tokens: ​I have heard in many forums that it is possible for me to send this JWT web token as a "Bearer token" in the authorisation header. It means firestore magically does all the authorization for me. Anything else I should be doing?
1) I believe I need to sign in using this custom JSON web token, and obtain an ID token. is that correct?
Sign in from a Firebase Client SDK
Use the Firebase Auth REST API to exchange the custom token to an ID token.
2) Then I need pass this ID token (not the JSON web token) to the Cloud Firestore endpoints when I am making a request for db access as an Authorization header set to Bearer {YOUR_TOKEN}.. Then you can access the Firestore REST API with the resulting ID token:
https://firebase.google.com/docs/firestore/use-rest-api#working_with_firebase_id_tokens
Imagine I embed into the header the bearer token also...using the JSON access token or the ID token I get from firestore
return this.http
.get(${OUR URL to app}, {
headers: new HttpHeaders().set('Authorization', Bearer ${JSON Web accessToken or ID Token})
})​
​User clicks on the URL that has this access token. They agree to terms and conditions and then I re-direct them to a cloud function that does some processing.​ This JSON Web token is passed along. I verify the JWT token also​ for authentication purpose using this code.​
function verifyToken(token) {
try {
var decoded = jwt.verify(token, constants.JWT_SECRET_TOKEN);
var admin = decoded.admin;
if (admin == "​XXXXXXXXX") {
return true;
}
return false;
} catch (err) {
console.log(err);
return false;
}
}
​any samples related to this will be helpful.​
related links I used
https://firebase.google.com/docs/firestore/use-rest-api#working_with_firebase_id_tokens
Firestore Custom Tokens
https://auth0.com/blog/how-to-authenticate-firebase-and-angular-with-auth0-part-1/
finally
Protocol specification for https.onCall
in https://firebase.google.com/docs/functions/callable-reference
Optional: Authorization: Bearer
A Firebase Authentication user ID token for the logged-in user making the request. The backend automatically verifies this token and makes it available in the handler's context. If the token is not valid, the request is rejected.
this is the official response I got from Google (but again works only if the user has an authentication request -- mean a valid firebase user I think), but what I want to know is using the Json web token itself can I achieve something like this.
Just to clarify, you'll need either a Firebase ID token or a Google
Identity OAuth 2.0 token to be passed on to the Cloud Firestore
endpoints as an Authorization header set to Bearer {YOUR_TOKEN}.
You may refer on the following links for more information on this:
REST API Firestore authentication with ID Token
https://firebase.google.com/docs/firestore/use-rest-api#authentication_and_authorization
Also, we don't have any samples related to this, but there's an
internal request to improve our REST documentation. I won't be able to
share you any details or timelines as to when it could materialize,
however, you may keep an eye out on our release notes or Firebase blog
for any updates we might have.
I am hopeful in stackoverflow I might get more samples related to this. But for now this is all what I got.

What does Ember-simple-auth check against?

I have been looking for answer of implementing ember-simple-auth (oauth2-password-grant) for days without luck. I use firebase to sign up users, which is successful. However on the log in page, the action of this.get('session').authenticate('authenticator:oauth2', credentials) seems to cause a json error (SyntaxError: Unexpected token < in JSON at position 0).
So my first question is, in theory, how does this authentication check if the user's email/password is correct? Meaning, in which file is the "answer" located? Am I supposed to define a token? If yes, I already tried "serverTokenEndpoint: 'http://localhost:4200/' or serverTokenEndpoint: 'http://localhost:4200/token" and nothing works. Thanks.
Ember simple auth sends login request to API(in your case Firebase). If entered credentials are valid your API will authenticate user, create and save auth token. Authenticated user with created token will be sent to Ember and token will be saved in local storage by Ember simple auth. Every subsequent request from Ember after login needs to include that token in its header and API will authenticate your request based on that token(comparing token from Ember with the one saved in API).

Using Firebase for server side authentication

I have Firebase authentication set up on the client side, and on the server side I can take a JWT token and decode the account ID. But how does this work when I want each page load to be authenticated on the server before the page is generated?
On login or each page load, can I simply store the last JWT token into cookies so that I can read them on my server? Aside from that, I don't know how else for my server to get that information aside from each link being an AJAX call.
This seems to be the only way to do it presuming you're using the firebase auth library to decode and verify the tokens on the server and not some kind of JWT parsing library.
Firebase admin includes methods for decoding and verifying id tokens and extrapolating all the information. This prevents cookie forgery and keeps firebase auth as your single source of truth for whether or not a user is authenticated.
for example (in node):
const admin = require("firebase-admin");
admin.initalizeApp({
credential: admin.credential.cert(yourServiceAccountJsonHere),
databaseURL: "http://YOURDATABASE.firebaseio.com/"
});
admin.verifyIdToken("usertokenasastring") //returns a promise
.then(function(decodedToken){
//process the decoded user token somehow
});
Firebase makes a call to your database, and makes sure that that user is logged in and that all the other information in the JWT makes sense, so you don't have to worry about implementing any kind of verification server side.

django rest framework - token authentication logout

I have implemented the Token Authentication according to the django rest framework Docs.
Form what I read, the Token Authentication of DRF is quite simple - one token per user, the token doesn't expire and is valid for use always (am I right?).
I understand that there are better practices out there, but for now the DRF token authentication is fine for me.
my question is- what is the best practice for logout with the normal DRF token authentication?
I mean, when the user logs out, should I delete the token from the client side? and then on login get the token again? should I delete the token and generate a new one?
Anyone with experience with this?
Here's a simple view that I'm using to log out:
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
class Logout(APIView):
def get(self, request, format=None):
# simply delete the token to force a login
request.user.auth_token.delete()
return Response(status=status.HTTP_200_OK)
Then add it to your urls.py:
urlpatterns = [
...
url(r'^logout/', Logout.as_view()),
]
WHOLE IDEA OF TOKEN AUTHENTICATION:
Normally in authentication services, there is a lifetime associated with a token. After a specific time, the token will get expired. Here, we get an access token which has an expiry time sent along with it by the server. Now the client needs to send this token everytime in the request header so that the server can identify who the user is. Either we can keep track of when it expires or we can just keep using it until we get an INVALID_TOKEN error. In that case we would have to again get the token from the server.
The lifetime of the access_token is independent of the login session of a user who grants access to a client. OAuth2,lets say, has no concept of a user login or logout, or a session. The token is just used to identify the user if he is who he says he is.
The token is unique for a user and client. You may save it to cookies to enable something like remember me but on the server you don't need to delete it. Whenever the token expires, the client need to send a request to the server to obtain the token again.
Token Expiry in DRF Token Authetication:
Currently, DRF Token authentication does not support this functionality. You would have to implement it yourself or use a third party package which provides this functionality. It should check for token expiry and raise an exception if the token has expired.
To implement it yourself, you can subclass from the DRF Token Authentication class and add your logic.
You can even use a third-party package django-rest-framework-expiring-tokens.
Some References:
1. Token Authentication for RESTful API: should the token be periodically changed?
2. How to Logout of an Application Where I Used OAuth2 To Login With Google?
It sounds like SessionAuthentication is what you are really looking. You can start(login) a session via BasicAuthentication or TokenAuthentication. Then use sessionid as your "token" for the rest of api calls. The "token" expires when you logout or exceed certain timing.
If you run into csrftoken issue using session authentication, this could be a very helpful.