domain name is getting replaced with github.com in github ouath call - node.js

http://**XYZ.com**/login/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2F**XYZIP**%3A3000%2Fauth%2Fgithub%2Fcallback&scope=user%3Aemail&client_id=34940ae24cfd171d449a4
When I try to use domain name instead of IP on github oauth app callback url its giving me an error...
If I change it to:
http://github.com/login/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2F**XYZIP**%3A3000%2Fauth%2Fgithub%2Fcallback&scope=user%3Aemail&client_id=34940ae24cfd171d449a4
Then it will work but because of different callback URL in oauth it will show me mismatch callback URL.
Basically I am calling from react app front end and node JS back end and passport-git-hub that is in back-end
What am I doing wrong?

This is expected behaviour. When you login through a third party auth service They will call THEIR service and redirect to your service with a session key.
So, what happens is.
There is a Login button, user clicks it
It redirects to google/github/facebook login page where user puts the username and password and presses login.
If user authenticated it generates a session key and sends that session key with additional info(for example profile) to your callback page.
Your callback deserializes the request and generates the user session and profile object and such.
When you open your route passport middleware checks if the session is there, if it's there goes to next() otherwise sends some error as response.
Maybe I got the question completely wrong but this is some generalised flow.

Related

Reseting password issue in Node.js with JWT

I am facing an issue with reseting password when users forgetting their passwords.
So lets say my Frontend is published in IP say 12.12.12.12
And my Backend services are running in 12.12.12.12:3000/api
So a user is forgetting the password and clicks on forget-password button which calls the
following service:
POST - 12.12.12.12:3000/api/forgotpassword
body: email address
After controlling the email, a link like this:
GET - 12.12.12.12:3000/api/resetpassword?token={token}
is sent to provided email.
So the problem starts now. How would you open the frontend when this link is clicked?If the token is not expired and valid.
Is it a good idea to use redirect in here? lets say I redirect to reset password page like:
12.12.12.12/resetpassword
But in here how I add the token at the end? otherwise everyone will have access to this page.
Hope I managed to explain the issue.
One last issue is
res.redirect(/resetpassword) ---> 12.12.12.12:3000/api/resetpassword (doesn't open page)
the back-end url is not going to be exposed to user, you just send front-end password recovery page url and pass a token as get parameter.
reset page without parameter can be used to request recovery email and page with get parameter can be used to check the token with back-end to authenticate user and show it field.

Getting OIDC username after authorization

My goal is to tell if a user is authenticated, and get their name and email. So far, I can only do the first.
My server app is a NodeJS/Express router. The OIDC server is provided by my company, I believe is compliant, but not under my control. I can do an "Authorization code flow": response_type="code". My Node app eventually responds to the callback route and I can get the "code" and "grant_id" query string values. Other than knowing they exist and presuming that means the user is authorized, I have no idea what I can do with those values. It appears that the only scope that works is "openid".
If I can get the access_code, I can call the UserInfo service and get these values.
My other choice is to do an implicit call. Unfortuantely, the OIDC service it provides the "access_code" and other values after a hash mark on the callback. I believe the flow to be like this:
User makes call to Node app. Detects a lack of authentication, issues redirect to SSO service implicit authorization
User's browser follows redirect to SSO service implicit authorization. User fills it out and is successfully authenticated.
W3 returns a redirect to the provided callback URL.
User needs to cooperate with the app, somehow parse the query string parameters to get the access token and pass this back to the Node application.
The browser calls the provided Node callback application, but without the necessary access token.
I think I could make a proxy server to force OIDC to give my node server the request, just so I can get the access_token. It seems like a very convoluted way to do this, so I have to think there's some simpler way.
Again, all I want is to know the user is authorized to use the app, and what their name and email is. It should not be this hard.
You can use the ID-token to get the details about the user.
It is also important that your identity provider is all about authentication. Final authorization checks should be done in the client, by examining the scopes/claims in the token.

Steam authentication API, passing data back to Angular

I have this problem with Express(NodeJS)/Angular web app where I rely on Steam's login authentication. Essentially when the user clicks "Login" he's redirected to the Steam authentication(Steam's website), once logged in the user is redirected back to a specific route on my backend called /verify. Once the user hits /verify there are session variables containing necessary user data to access. Therefore I use JWT to generate a token with this data to send back to the client(Angular in this case).
The problem is sending this token back to the frontend(the client) to save in local storage.
Any help is highly appreciated! Currently, I pass the token via a query string with a redirect back to the frontend, but this doesn't seem like a good solution.
Maybe I should stick to server-side sessions and write HTTP routes to GET user data. The problem with this approach is once again the client is completely unaware when the user authenticates himself on the backend, since the only callback is triggered is on the backend.
EDIT:
Tried another approach, however once again unsure of it's the right way to go both code-wise and security-wise.
Redirect the user to the Steam authentication page.
Wait for the authentication callback on server side, in my case it hits the route '/verify'.
Once at /verify the session cookie is already set, therefore I redirect the user back to my Angular app to a specific route called '/login'.
On /login the user requests a token based on the session cookie on the server, the token in my case is a JSON Web Token(JWT).
Once the token is saved in local storage I simply redirect the user to any page in my Angular app.
If this is the wrong way to do it, please let me know!

SAML2.0 Authentication with Node.js and SPA

I've been scratching my head for about 2 days on how to solve what seemed to be a simple task, but it's starting to drive me crazy.
I have an application where users will use SAML 2.0 to authenticate.
I have a react-application set up for the front-end, and was thinking I was gonna use JWT to secure the rest-api communication between front-end and backend.
When a user signs in, the flow is the following:
User accesses www.server.com/ and gets served the static HTML with react-application
User clicks 'Sign in' and accesses www.server.com/login
passport-saml redirects user to saml identity provider. User logs in.
User calls back to www.server.com/callback with a SamlResponse in the req.body which is decoded by passport-saml and put into req.user.
If the user doesn't already exist, I create the user in the database.
I create a JWT.
What should I do next? The problem is that the user is not in the react-application when calling back from the identity provider, so I've lost all state in the application, so whatever I reply with will get sent to the browser.
Is there any way I could force the browser to give me the SamlResponse which the identityprovider is calling back with? Then I could send it to the server as a http-request from the react-application.
After some thinking, I came up with the following solution which worked quite nicely for me.
SAML has something called RelayState which is a property that the Service Provider has to respond with. So now the process looks like this:
User accesses http://frontendserver.com and gets server the static page with the React application (not signed in.).
User clicks 'Login' and gets redirected to http://backendserver.com/login/?RelayState=http://frontendserver.com which authenticates via passport-saml and redirects user to SP. So I pass the origin of the request in RelayState.
User calls back to http://backendserver.com/callback with the SamlResponse, which includes the RelayState.
I create a token, and redirect the user to RelayState/#token.
I can then parse the url in the React application, and add the token as a header for any further requests.
This might've seemed like the obvious way to do it, but it took me quite a while to figure out that this would work.
I know this question is for Node backend, but I found an article of the implementation for a PHP/Apache webserver backend here and I think it can help someone trying to understand the flow of the process of how this type of thing works.

Authorising Client Routes in a Single Page Application

I'm writing a SPA that uses SammyJS for the client routing. A user is either authenticated or not, and I would like to filter access to the client routes they can access.
For example, say I have two client routes '#/public' and '#/private'. The user has to login to access '#/private'. The login part works fine, user enters username and password, calls the RESTful API (sitting on NodeJS) and is returned an authentication token. They are then redirected to '#/private'. The obvious problem though is that anyone can call '#/private'.
I was thinking of calling SammyJS before() on the '#/private' route and checking the user is authenticated. Has anyone else tried this approach ?

Resources