how to implement token based authentication in ionic 2 - ionic2

I want to implement a content based application say based on fetching journals adding to user reading list and first need to check user ip address and then create a login form along with authentication and after that generate a token and the token need to be stored in localstorage and token needs to be accessed till logout

Related

How to detect the logged in user from Keycloak OpenID logout_token on back channel logout?

First let me describe the setup:
We have a frontend Angular based product from a different client team (not part of code we can easily modify), and a backend django based API server.
The front end logs in to a keycloak server, and when logged in, the backend gets an Auth header with a bearer token in every request.
From this, we are able to identify the logged in user as follows (using python-keycloak):
ret = keycloak.userinfo(bearer_token)
username = ret['preferred_username']
This is obviously very wasteful since it needs an extra network request to keycloak everytime - so we create a django user session instead and use that for session management.
Now when it comes to logging out, when the user logs out from the front end, we need to void the django session.
I've setup the "Back channel logout URL" on the keycloak realm settings to call some endpoint on the django server.
The endpoint gets called on logout, and it gets a "logout_token" value in the arguments.
Now I'm not sure how I am supposed to identify which user is logging out based on this token. How can this be done?
Thanks in advance...
I am not 100% sure about the soundness of you architecture. Nonetheless, regarding your particular question:
ret = keycloak.userinfo(bearer_token)
username = ret['preferred_username']
From the Keycloak book:
preferred_username This is the username of the authenticated user. You should avoid this
as a key for the user as it may be changed, and even refer to a
different user in the future. Instead, always use the sub field for
the user key.
From the OpenID connect specification one can read that:
OPs send a JWT similar to an ID Token to RPs called a Logout Token to
request that they log out. ID Tokens are defined in Section 2 of
[OpenID.Core].
The following Claims are used within the Logout Token:
iss REQUIRED. Issuer Identifier, (...)
sub OPTIONAL. Subject Identifier,(...)
aud REQUIRED. Audience(s), (...)
iat REQUIRED. Issued at time, (...)
jti REQUIRED. Unique identifier for the token, (...)
(...)
sid OPTIONAL. Session ID - String identifier for a Session. This represents a Session of a User Agent or device for a logged-in End-User at an RP. (..)
A Logout Token MUST contain either a sub or a sid Claim, and MAY contain both. If a sid Claim is not present, the intent is that all sessions at the RP for the End-User identified by the iss and sub Claims be logged out.
So you can try to use the claim 'sub', which is the unique identifier of the authenticated user. You would (probably) need to create the mapping between 'sub' and 'user' in your backend. Alternatively, you could use the same logic but applying it to 'sid' instead. There you would map the ID session of Keycloak to your own ID session.
However, my question is:
The front end logs in to a keycloak server, and when logged in, the
backend gets an Auth header with a bearer token in every request.
From that bearer token (which I am assuming to be an access token) can't you simply get 'preferred_username' (or better the 'sub' claim) from there? that would not require any extra call to the Keycloak server.

Is saving user's id and login token in local storage a good idea?

I am developing Django + React project and I'm caught with this security approach concerning login and managing views for the logged in user.
I am using django-rest-framework or DRF for my RESTful API. And I'm using django-rest-knox for authenticating user logins since I am implementing Token-based authentication (instead of session-based which uses CSRF).
Question: Is it a good idea to save user's id and token in local storage?
Currently, I have a /auth/login/ API endpoint that handles the backend logic of logging in user and returns JSON response of login details upon successful login (including user id and token).
In my frontend, I use redux and redux-persist so the user's login details are kept even when the site is refreshed. The way redux-persist do it is that it saves the response in local storage. This means that the user id and token can be accessed and changed anytime thru dev tools.
If user will then make a POST request to an API that requires a Token authentication header, the frontend will look into that local storage for the token value to be supplied to the request header.
If user will then make a POST request to an API where the user id is required in the request data, the frontend will also look for the id in the local storage.
Localstorage is not safe, especially for storing tokens and ids. Any user can go to the browser's developer tools, see and also edit its contents, for example.
You could check on Django's sessions, so you can store data securely at server side and keep its contents associated with a specific user. There is a great tutorial at Mozilla that explains sessions in a clearer way than the official documentation.

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.

Reactjs - Current User from JWT token

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.

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/