Reactjs - Current User from JWT token - django

So, I have created a django-rest-framework backend with JWT Authentication and now, I am trying to solve the problem where when user manually provides a URL, I have to check If the user was previously logged in.
So since, I am storing the token to localStorage when the user logged in. I am doing this:
componentDidMount() {
if (localStorage.getItem('token')) {
// fetch current user
this.props.ctx.toggleLoggedIn()
// this.props.ctx.setUsername('')
}
}
If I find a token in localStorage, then I have to fetch the current User and then, toggleLoggedIn and also set the current user's username in the context.
So, I am planning to create another API end-point which provides the current user when a token is given. The problem is I don't know how to start that!

It might be that i misunderstand, but for me it seems like you're trying to solve this a bit backwards. When the user login, get token and store this in localStorage. Right after login fetch the user profile and store this as well.
If the user manually provides a url, you should now have both token and user. If you don't have a token or it's expired, redirect to login page and clear local storage.
I would create a higher order component that checks if the token is valid and use this for all "protected" pages.

Related

Get user from refresh token in Django Simple JWT's TokenRefreshView

I am trying to check if the user still exists when Refreshing the Token, returning the user's updated detail (if updated) upon refreshing a token. Is there anyway to retrieve the user's details from the refresh token? [request.user] is currently marked as AnonymousUser so I am unable to know who the refresh token belongs to.
I think it is a good practice to have one endpoint to one type of job. In your case, it will be good to have:
endpoint for a token refresh,
endpoint to get user details.
Please take a look at Djoser package. It has predefined views and URLs that you can reuse.
If you really want to get some user info on refresh, then you can try to put some user's information in jwt payload part. But I would rather go with to separate endpoints. If user will not exists, then refreshing the token won't return new token.

Handling the oauth token in a website/service

I have created a website which allows the user to authenticate against oauth2 (from another provider), the basic flow is (assuming a new user):
The user loads my webpage
An OAuth request token key and secret is provided by the OAuth endpoint
I store the request token into the user's cookies
The user is redirected to the OAuth authentication page from an external provider
The user accepts and is redirected by to my webpage with URL parameters which specify the OAuth verifier and OAuth token
Using the request token (retrieved from cookies) and OAuth verifier (passed via URL parameters), I am able to get an access token key and secret from the OAuth endpoint.
I am now able to authenticate with the providers API and use that to get the logged in user ID.
I then store into a MySQL database, the user ID, a token which I generate as a random unsigned integer, OAuth token and OAuth secret. In cases of the token I generate already being in the database, I just continue in a loop until a unique token is generated. The MySQL database has a strong name, username and password. The database user can only access the table in question and only has privileges to add an entry, delete an entry and make a query.
I clear the request token from the user's cookies and instead store the user ID and my generated token.
When a user comes back to my website, I check if they have the user ID and token stored in their cookies, if so I attempt to look up the OAuth token and secret from MySQL. If they are found, I test they are still valid (does the API endpoint accept them) and if so, the user remains 'logged in' to my website. In cases where the user ID or token isn't found in MySQL or cases where it is found, but is not accepted by the endpoint (expired?), I just go back through the flow above.
The above all works correctly, new users can successfully authenticate, returning users find the website remembers them. I do not expose the OAuth token key or secret to the user and instead, give the user this token ID which I generate.
Are there any problems with what I am doing?
Should I be encrypting the OAuth token key and secret in my database?
Is there a problem with the fact if someone was to gain access to the token I generate, along with the user ID, they would be able to call my scripts. Is this a problem?
Should I be encrypting the user ID and token I generate before storing it in the user's cookies? Taking into account, ultimately whatever is stored in the user's cookies will get passed to my script, so if I were to encrypt, store to cookies, then next time read from cookies and decrypt, the user would still be able to access my endpoints by simply passing the encrypted version (assuming the server decrypts, if the client decrypts then the decryption key would be accessible via the users browser anyway), which doesn't immediately appear to offer any further security.
My goal is to tighten up the steps above so it is deemed robust and secure. The actual use case for my web site means it'll only have a tiny number of users (if any) using it. It was more of a learning process for me, combined with implementing something I actually need. But for the learning aspect alone, I would like to make everything sensible and secure. I am not trying to be overly pedantic and implement steps no other similar websites would implement, basically I would like my site to be secure enough that if there ever was a problem, no one could point a finger at me and say I didn't implement an adequate security system.

Using Firebase Auth with Django

I want to use firebase authentication for my django webapp. To achieve this, I think would I need to write a custom auth backend - is that right? I don't see any libraries that already do this - django-allauth looks like it comes pretty close as an alternative but I am interested in the phone number verification provided by firebase.
I'm also confused about what happens to the User model and functions like request.user or user.is_authenticated. Right now I use the authenticate and login functions - how does django know that a user is logged in via firebase? Would I still be creating a User model for every user?
Thanks
You can use Firebase Auth with any framework. You don't necessarily need to use custom auth. Typically, you would sign in the user on the client, get the ID token by calling firebase.auth().currentUser.getIdToken() and then pass the ID token to your server, verify it and parse its payload identifying the user ID and its other claims by using the Firebase Admin SDKs and then you can issue a session cookie identifying the user associated with that ID token.
On signout, you would clear that session cookie.
If you also need to persist that user on the backend after setting the session cookie, you can also use the Firebase Admin SDK to lookup a user identified by the user ID or just use the token claims to populate the user without any network call. You can populate that in the user model of associated framework if needed.
For more on session management, you can refer to this django documentation: https://docs.djangoproject.com/en/3.0/topics/http/sessions/

Working with django rest framework to authenticate a user with new token for every login

I would like to use django-rest-framework token to authenticate users. My workflow would be:
User requests a page
If auth token is present, respond with the requested data.
If auth token is not present, redirect to the login page (with the request page).
Inside the login page, user submit their credentials
If credentials were correctly authenticated, get or create a token for that user and redirect back to the requested page with the token.
Else, respond with error.
Lastly,
When the user logs out, delete the token for that user.
So my question is, is it okay to delete and create a new token for every login if the user has already logged out? Also I assume the token will be unique, am I correct? Your help and guidance is very much appreciated. Thank you.
A REST API should be stateless, that means that there should not be a "session" hence no login and no logout, and no redirections to a login page.
If the request doesn't have a token then the API should return (probably) a 401 Unauthorized HTTP status code and not a redirection. You're making an API so there won't be human interaction. Django rest framework offers a human-friendly interface that does have sessions, login/logout, and if that's all you need the go for it, you can do whatever you want. But It'd be hard for another program to use your API.
why not using tokens with expiration dates or using another well known authentication method ?? :P
Hope this helps :)

How to delete an apprequest

According to the documentation I must remove an apprequest when a user has accepted it. There is however a problem with this.
When I accept an apprequest, I will be redirected to my app. But in the url parameters only the apprequestid(s) are included. The userId of the current user is unavailable.
My app doesn't require authentication so I can't access the current users data.
How do I remove the apprequest for this user when I don't have acces to the userdata or accesstoken as described here:
The old method of the apprequest allowed me to extract the userid from the requestid. This is not possible anymore.
you have to have authentication to "tamper" with user data - that includes app invitations.
However with an App Access Token you might be able to delete the post without authenticating your user (you'll still have to aquire their UID - possibly from the signed_request . You can read at this link about app login and how to retrieve the correct access token.