I am wondering about some strategies regarding a particular issue I am facing. Let's imagine that there's an authentication system implemented using JWT.
Users sign-in, they get a token which has the following payload:
{ username: 'John', email: 'john#example.com', photo: null }
(they payload is generated based on a database query, say SELECT * FROM user WHERE id = 1)
When (and only when) the user is logged in, they can upload an image. The image gets stored somewhere, the user entry is updated in the database.
The problem I am facing is that now they need to login and log-back in again to see the profile photo updated since the profile information is displayed based on the token payload which will still not contain the photo. The next time they login of course it'll be updated:
{ username: 'John', email: 'john#example.com', photo: 'john-img.jpg' }
So the question is - how to handle the situation when the profile data is show from a token and there's a file upload procedure and I wish to display the image?
I know that the client shouldn't (and cannot) update the token, because that will automatically cause the token to be invalidated.
Are there any strategies out there that are acceptable? Should I rethink the logic of doing file uploads while logged in? Should this not be tied to a JWT? Should the profile page not be built up from the token?
#Tamas you should never keep user photo in JWT Token, as this is not the ideal or recommended way, instead you can keep this in User(database) table and always update user data on profile update,
But if they really want to go with this option only? you can still do this by keeping user image info in localstorage, by the time user login and logout you can get image info from localstorage.
hope this could help.
Related
Basically,
I have SPA app with JWT authentication. Now my question is, there is a page that has follow button, so on the first load of page, I need to know if user is logged in or not, so I can disable/enable button.
Approach 1: Before page load send access token and if it is successful render like user is logged in, if it fails render like user is logged out
Approach 2: When user is logged in, keep that state in LocalStorage and just check local storage and render page from that
Is it correct to just keep state of logged in user in LocalStorage? I think that is where you should store ID token (if you use them) that only has user profile information?
Of course I will check access token on each request and from response I can change state in LocalStorage. Problem is that on initial load of page, should I check access token server-side before rendering?
If I keep state in LocalStorage than that user will be logged in on that device basically indefinitely, until he clicks "log out" or tokens fail?
Can anybody see potential problems with keeping state in LocalStorage?
It's OK to keep this information in the local storage. I mean, you can keep a variable there, that will just tell you "this user is logged in as userX". You can then safely utilize this information to display information on your page (e.g. Hi userX!). Even if someone manages to steal that information, it doesn't give them much information.
As you said, you will have to check the credentials on every request anyway (access token, session cookie, etc.), so it's not an issue to have this non-sensitive data in the local storage.
You can of course go with approach 1, but in my opinion, it's just adding unnecessary traffic.
If it bugs you that it will seem that the user is logged in for ever, then you can also persist some TTL in the local storage, and after that TTL treat the user as logged out.
I have a Desktop Application developed with python and pyqt5.
I want to implement a login system for some reasons.
the scenario will be like this (this section is done so far):
Client has created an account on my website and downloaded my desktop application.
They run the application for the first time => A login window displayed asking users to input their data.
The application made a request to URL: http://ip/api/login with a JSON object {username, plaim_pw} (the API developed with Flask).
The API will process that request and check whether that user's data inside that request exist or not and if that PW is correct or not then it will return a response.
If the user successfully logged in then every run time the app will not ask the user again about his/her data, it will be stored somewhere in their machine.
What I want is:
If user ' A' successfully Logged in with account ' X', And at the same time user 'B' trying to log in with the same account that user ' A' is using => Then I want to tell user 'B': "can't log-in at the time because another user using the same account" or something like that. in short description: only one user can use the same account at the same time.
My questions are:
How to accomplish that mechanism? is it good or bad?
I read about JWT, could it be helpful in my case? If so, Then how should I implemented it?
Here is extra information:
I don't have many APIs, I only have a route for "login" nothing more for now, And I want the login system for some reason.
And in the future, I will be using HTTPS instead of HTTP.
Once the user has logged in write this down on the server. Then the subsequent login attempt can check this. When checking consider an expiration timestamp. This can easily solve the first question. Consider looking at topics such as session management: https://en.wikipedia.org/wiki/Session_(computer_science), https://en.wikipedia.org/wiki/Session_ID.
JWT is not necessary for your scenario yet.
I have a React Native app that uses Strapi for its main API.
Some of the API endpoints require authentication so I've used the Auth0 provider and that's all working fine.
A user is now able to log in and I'm securely storing their access_tokens.
So far, Auth0 only gives me an access_token, a refresh_token, an id_token (jwt containing name and email etc) and expiry times for the tokens.
But I'm wondering if it's possible to be able to store a users preferences like whether they prefer dark or light theme etc and extra info such as a user_id in Strapi and let them update it after logging in with Auth0.
The catch is that only that user should have read/write access to their own data.
I can't see any docs or guidance on this kind of thing. Has anyone else managed to implement this kind of thing and if so, a rough approach would be great!
Thanks!
Well, one way of the doing this is creating a OAuthUsers collection in strapi, which will hold basic details of a user like:
first_name
last_name
email
When a user registers on Auth0 and returns back to your site, you can take the basic details that were returned from the identity management platform and store it in strapi under the OAuthUsers collection.
Now, coming to your question on how to store the preferences of the user, what you can do is create another collection called preferences with following attributes:
is_dark_theme
OAuthUser (Make this a one-to-one relation with OAuthUsers collection )
Every time a logged in user updates his preferences it will first come and create an entry in this collection if not already existing. How you can check if an entry exists for a user is by using the email from the JWT token itself, that you attach as the bearer token on the API calls. I will assume, you already know how to decode a JWT token.
So a rudimentary design would be like so:
const is_dark_theme = request.body.is_dark_theme; // 1 or 0 for light theme
const user = await strapi.services.OAuthUsers.find({ email: '[email from JWT]'});
const preference = await strapi.services.preferences.find({ OAuthUser: user.id });
if(preference)
await strapi.services.preferences.update({is_dark_theme}, {id: preference.id});
else
await strapi.services.preferences.create({is_dark_theme, user: user.id});
So per this, what will happen is the user will only be able to update his own details and never be able to touch the preferences of other users as the user will only be able to pass the is_dark_theme parameter from front end and rest of the information will be taken from the JWT token.
I'm trying to make a check for a specific user logging into Instagram and approving an app I've created. Is this possible?
Example flow :
User comes to my app
User clicks login/authenticate via Instagram
User logs in (or check is made if user is logged in via Instagram)
User is redirected to my app's callback URI.
When the user gets back to my app I would like to be able to check which user has authenticated - is this possible? At present I'm only able to get an access token.
Thanks for any help.
I've actually solved this by using the server-side flow mentioned in the API documentation (http://instagram.com/developer/authentication/) which gives me back a response including the details of the user logged in if following the extra step (code->access_code application, etc).
I also figured out what you mention above too, so both ways are good.
Thanks for you help.
The information is not directly returned to you in the OAuth process, but once you have the access token you can load user information using the https://api.instagram.com/v1/users/self/?access_token=XXXX endpoint. That will give you data about the currently logged in user (including ID and username)
I have a unique user creation flow which is as follows:
User comes to my site for the first time and they click a button.
I create a User in the DB for them and set a localStorage key with the UID.
Use goes about creating data and I save the data in the DB and associate it with the UID.
User comes back, and if they have UID set in localStorage, I show them the data they previously created.
User can click Register to create a "real" account from which point they will have to login with username and password or another service (e.g. Facebook).
So, how would I accomplish this with Meteor Accounts and the User model?
In a nutshell:
I need to create User mongo document with no information (about the user).
I need to authenticate a user by just having a UID (acting as a "password").
Register onCreateUser to add an "anonymous" field ({anonymous:1})
when a random password is used, maybe generated with Meteor.uuid().
Add a timestamp field
({created:new Date()}) to clean out old, anonymous accounts.
Perform old anonymous user maintenance, like deleting anonymous users more
than one hour old:
Meteor.autorun(function()
{Meteor.users.find({anonymous:1,$where:"new Date() - this.created >
360000"}).forEach(function (user) {
Meteor.users.remove({_id:user._id})}});
On the client:
Always prompt
for a "nickname." This will become the official username, or will
sit in the system forever used.
Check if client is logged in. If
not, create a user with nickname and a "magic number" password,
which logs you in. When they click register, write "Register" at the
top, but actually just change their password and $set:{anonymous:0}
Don't use localStorage, and don't use UIDs. The session cookie IS your UID.
I don't know how to help with the authentication, but as for creating a blank User object, I've successfully done the following on the server-side (with a different name...):
Meteor.users.insert({profile: {name: 'Oompa Loompa'}, foo: 'bar'});