How to display that a user is connected to GitHub - node.js

I am developing a website like Heroku. I confused what should I do with the Github OAuth part? when you wanna register in Heroku and login you can not use OAuth ways (login/register using Github).
but after login you can create App. now one of your options to upload your codes in the Heroku is to connect your Heroku account to your Github account.
My problem
When the user is logged in how could I redirect the user to another page and after authentication (Github OAuth) how could I detect that this user previously logged in and the user does not need re-login?
Exactly what the Heroku did.
I can not understand how can I send another data to the Github OAuth login page and retrieve it back in callback url to detect which user is logged in now and save his/her access_token & refresh_token in database.
Not that I use expressjs express-session sequelize and ejs.

GitHub, like all OAuth based APIs, requires that each request to the API made on behalf of a user is authenticated with an access_token. If you don't pass an access_token alongside your request, the request will fail with a 401 Unauthorized status code.
There's no way to ask GitHub if a random user has accepted your app. It's not something implemented in the OAuth framework - as it could lead to a security flaw. So it's your responsibility as the application's owner to record which user has authorized your app.
With this in mind, let's try to sum up the differents steps that Heroku had to achieve to display this "Connected" status under the GitHub logo.
When you've signed-up on Heroku, the status of the GitHub integration was "not_connected". If you visit the settings page, you would see a "Connect to GitHub" button.
At some point, in the Heroku dashboard, you have clicked on the "Connect to GitHub" button and have authorized Heroku's app for GitHub. This is where you've been redirected to the callback_url
At this particular time, while you were on the callback_url page, Heroku has recorded in its database the new status of the GitHub integration for your account. It was set to "connected". Heroku has probably saved alongside the access_token and refresh_token.
Every time that you visit the settings page of your app, Heroku can render that you are connected because it has the status in its database.
(optional) When Heroku performs requests to the GitHub API using your access_token it can confirm that the connection is still live. If ever the request failed with a 401 Unauthorized, Heroku can update its database and reset your GitHub integration status to "not_connected".
This work like this for the GitHub API, as well as with any other OAuth based APIs. If you plan to integrate with several APIs, I highly recommend you to use an API Integrations Manager, such as Pizzly. It will help you focus on the business logic ("is my user connected or not?") and totally handle the OAuth process for you.

Related

How to logout from Oauth signed in web app with GitHub?

I have implemented OAuth using GitHub on my web app, so when I log in using GitHub I get logged in successfully. I wanted to know how to implement logout so that I get logged out of the web app.
when the user visits www.localhost:3000/login and clicks login/signup with GitHub, the user gets redirected to the GitHub login page, user logs in with his/her GitHub account and gets redirected to localhost:3000/homepage,
I sent a cookie from the server side for session purposes and get a cookie from GitHub (don't know why).
when I clear cookies from localhost:3000 and visit localhost:3000/login and hit login with the GitHub button I get logged in with the previously signed-in user account automatically. However, when I clear all cookies from www.github.com and do the same, this time it prompts the user to log in with the git account again.
I have not used any external library like passport.js for OAuth and also I don't want to use any.
so how to implement this logout that logs out of the GitHub OAuth session?
What you want is "single log-out" whereby logging out from your application also logs out from GitHub. But the relevant specification has been finalized only in September 2022 and I could not find any mention of it at docs.github.com. Perhaps this is also not desired, since GitHub sessions are long-lasting: Revisiting github.com with the same browser after a few days does not require a re-logon.
But as an alternative to logging out from GitHub upon logout from your application, you could require a renewed consent upon re-login to your application. If you have already been logged in once to your application via GitHub and then visit
https://github.com/login/oauth/authorize?scope=user:email&client_id=...
you are re-logged in silently. But if you visit
https://github.com/login/oauth/authorize?scope=user:email&client_id=...&prompt=consent
instead, the GitHub consent screen re-appears. (The parameter prompt=consent is not documented on docs.github.com, but is explained here.)
Perhaps that is sufficient to satisfy your requirement.

How do you implement a custom login UI when using PKCE in auth0?

I am setting up a login system in auth0 for a React Typescript application. Due to how the application works I am using the PKCE flow for authentication and authorization to get access tokens and refresh tokens. So far I have implemented the flow by adding a node js express server that fetches the access token and refresh token from auth0 once we have the authroization code after logging in through the /authroize endpoint on auth0. However the problem we have now is that we cant implement our custom UI onto the login page since when we hit the /authorize endpoint we are sent to the login page hosted at auth0. We would want to set up our own login form and send over the details to auth0 in order to fetch the authorization code. Is there a way to login through our own login page instead of using the one hosted by auth0, by for example hitting the right endpoint in their api to fetch an authorization code? The only other option I have seen is by changing the HTML under branding in the application dashboard but I have also read that auth0 does not recommend doing this.
I have also previously used the auth0 js SDK and there I was able to use our own custom page for login, however that SDK uses the implicit flow which does not issue refresh tokens and cannot therefore be used. In the other SPA sdk, you cant add your own UI for login since that redirects you to auth0 as well.
Assuming that you still use the Node.js server in addition to the SPA, you can ask the user for username and password, send it the Node.js server. Using the Resource Owner Password flow, the Node.js server can then request the access, refresh and ID tokens.
Please study the security implications carefully, in particular related to this authentication flow.
By implementing custom login UIs, you lose many things: hardened security of Auth0 servers, easy configuration of authentication methods without changing the application, use of ready-made Auth0 SDKs etc. I would carefully consider if it is worth it.

Accessing Third Party Apps After Creating A Session Via API Token

I've scoured the api docs, as well as StackOverflow, and I've yet to find the answer to my question. And it is possible I'm misunderstanding how the system works.
Here's the scenario our client wants:
User logs into our website
At which point we authenticate the user in our system, and One Login via the api.
After the user logs into our dashboard, they can click an link and be redirected to their third party analytics app due to the fact that I've created a new session with One Login.
Here are the steps I've completed.
I've successfully received an access token via --> https://developers.onelogin.com/api-docs/1/oauth20-tokens/generate-tokens
I've successfully used the access token to generate a session login token via --> https://developers.onelogin.com/api-docs/1/users/create-session-login-token
I've successfully used the session login token to create a new session.
I'm receiving the proper cookies from One Login after making the create new session request, and - at that point - if I enter the URL onelogin.com/login, I am taken directly to the dashboard.
At this point I know I'm properly authenticated with One Login. However, I'm not sure how to directly access a third party app from a link on our website.
Thanks.
Two ways:
If the app supports SP-initiated SAML, just navigate the user to the application and it'll do the whole SAML flow- App redirects to OneLogin - OL authenticates user (because you have a session) --- redirects SAML to app
Use the launch endpoint - You can create a URL to an app by using this format: https://app.onelogin.com/launch/{app-id}. For example, you can provide a link to an app like this:
Time Reporting
Details on that endpoint can be found here: https://developers.onelogin.com/api-docs/1/embed-apps/get-apps-to-embed-for-a-user
Take note that you're probably going to want to use the optional flag that makes sure to redirect to your login page, not OL's if you've built a login facade.

Post/share automatically to linkedin company page from server

I'm trying to post to my company page directly from my server, but I have a hard time understanding how the authentication works. All examples + the documentation seem to require you to have a callback where the "visitor" is promted with a form to confirm the access. But in my case, my app is supposed to only post to my company page and I didn't plan on building a gui at all.
I have setup the Client Id and Client Secret in the Linkedin developer section.
Even though you are the only one that's going to use the app, you still need to execute the OAuth flow and therefore authorize your own app to use your account. You can use Grant for that.
Another thing to note is how LinkedIn handles scopes. They changed how the permissions work earlier this year, so for certain permission you'll have to submit your app for approval.
Lastly LinkedIn doesn't give you a refresh_token so in order to refresh your access_token once it expires you'll have to use a similar hack as the one I described here for Facebook.

passport.js RESTful auth

How does one handle authentication (local and Facebook, for example) using passport.js, through a RESTful API instead of through a web interface?
Specific concerns are handling the passing of data from callbacks to a RESTful response (JSON) vs using a typical res.send({ data: req.data }), setting up an initial /login endpoint which redirects to Facebook (/login cannot be accessed via AJAX, because it is not a JSON response - it is a redirect to Facebook with a callback).
I've found https://github.com/halrobertson/test-restify-passport-facebook, but I'm having trouble understanding it.
Furthermore, how does passport.js store the auth credentials? The server (or is it service?) is backed by MongoDB, and I'd expect credentials (login & salted hash of pw) to be stored there, but I don't know if passport.js has this type of capability.
There are many questions asked here, and it seems that even though the questions are asked in the context of Node and passport.js the real questions are more about workflow than how to do this with a particular technology.
Let's use #Keith example setup, modified a bit for added security:
Web server at https://example.com serves a single page Javascript client app
RESTful web service at https://example.com/api provides server support to rich client app
Server implemented in Node and passport.js.
Server has a database (any kind) with a "users" table.
Username/password and Facebook Connect are offered as authentication options
Rich client makes REST requests into https://example.com/api
There may be other clients (phone apps, for example) that use the web service at https://example.com/api but do not know about the web server at https://example.com.
Note that I'm using secure HTTP. This is in my opinion a must for any service that is available in the open, since sensitive information like passwords and authorization tokens are passing between client and server.
Username/password authentication
Let's look at how plain old authentication works first.
The user connects to https://example.com
The server serves a rich Javascript application which renders the initial page. Somehwere in the page there is a login form.
Many of the sections of this single page app haven't been populated with data due to the user not being logged in. All these sections have an event listener on a "login" event. All this is client side stuff, the server does not know of these events.
User enters his/her login and password and hits the submit button, which triggers a Javascript handler to record the username and password in client side variables. Then this handler triggers the "login" event. Again, this is all client side action, credentials were not sent to the server yet.
The listeners of the "login" event are invoked. Each of these now needs to send one or more requests to the RESTful API at https://example.com/api to obtain the user specific data to render on the page. Every single request they send to the web service will include the username and password, possibly in the form of HTTP Basic authentication, since the service being RESTful isn't allowed to maintain client state from one request to the next. Since the web service is on secure HTTP the password is safely encrypted during transit.
The web service at https://example.com/api receives a bunch of individual requests, each with authentication information. The username and password in each request is checked against the user database and if found correct the requested function executes and data is returned to the client in JSON format. If username and password do not match an error is sent to the client in the form of a 401 HTTP error code.
Instead of forcing clients to send username and password with every request you can have a "get_access_token" function in your RESTful service that takes the username and password and responds with a token, which is some sort of cryptographic hash that is unique and has some expiration date associated with it. These tokens are stored in the database with each user. Then the client sends the access token in subsequent requests. The access token will then be validated against the database instead of the username and password.
Non browser client applications like phone apps do the same as above, they ask user to enter his/her credentials, then send them (or an access token generated from them) with every request to the web service.
The important take away point from this example is that RESTful web services require authentication with every request.
An additional layer of security in this scenario would add client application authorization in addition to the user authentication. For example, if you have the web client, iOS and Android apps all using the web service you may want the server to know which of the three the client of a given request is, regardless of who the authenticated user is. This can enable your web service to restrict certain functions to specific clients. For this you could use API keys and secrets, see this answer for some ideas on that.
Facebook authentication
The workflow above does not work for Facebook connect because the login via Facebook has a third party, Facebook itself. The login procedure requires the user to be redirected to Facebook's website where credentials are entered outside of our control.
So let's see how things change:.
The user connects to https://example.com
The server serves a rich Javascript application which renders the initial page. Somehwere in the page there is a login form that includes a "Login with Facebook" button.
The user clicks the "Login with Facebook" button, which is just a link that redirects to (for example) https://example.com/auth/facebook.
The https://example.com/auth/facebook route is handled by passport.js (see the documentation)
All the user sees is that the page changes and now they are in a Facebook hosted page where they need to login and authorize our web application. This is completely outside of our control.
The user logs in to Facebook and gives permission to our application, so Facebook now redirects back to the callback URL that we configured in the passport.js setup, which following the example in the documentation is https://example.com/auth/facebook/callback
The passport.js handler for the https://example.com/auth/facebook/callback route will invoke the callback function that receives the Facebook access token and some user information from Facebook, including the user's email address.
With the email we can locate the user in our database and store the Facebook access token with it.
The last thing you do in the Facebook callback is to redirect back to the rich client application, but this time we need to pass the username and the access token to the client so that it can use them. This can be done in a number of ways. For example, Javascript variables can be added to the page through a server-side template engine, or else a cookie can be returned with this information. (thanks to #RyanKimber for pointing out the security issues with passing this data in the URL, as I initially suggested).
So now we start the single page app one more time, but the client has the username and the access token.
The client application can trigger the "login" event immediately and let the different parts of the application request the information that they need from the web service.
All the requests sent to https://example.com/api will include the Facebook access token for authentication, or the application's own access token generated from Facebook's token via a "get_access_token" function in the REST API.
The non-browser apps have it a bit more difficult here, because OAuth requires a web browser for logging in. To login from a phone or desktop app you will need to start a browser to do the redirect to Facebook, and even worse, you need a way for the browser to pass the Facebook access token back to the application via some mechanism.
I hope this answers most of the questions. Of course you can replace Facebook with Twitter, Google, or any other OAuth based authentication service.
I'd be interested to know if someone has a simpler way to deal with this.
I greatly appreciate #Miguel's explanation with the complete flow in each cases, but I'd like to add some on the Facebook Authentication part.
Facebook provides a Javascript SDK which you can use to get the access token on client-end directly, which is then passed to the server and used to further pull all the user information from Facebook. So you don't need any re-directs basically.
Moreover, you can use the same API end-point for mobile applications as well. Just use the Android / iOS SDK for Facebook, obtain the Facebook access_token on the client end and pass it to the server.
Regarding the stateless nature as explained, when get_access_token is used to generate a token and passed to the client, this token is also stored on the server. So it's as good as a session token and I believe this makes it stateful ?
Just my 2 cents..
Here is an awesome article I found that can help you authenticate with:
Facebook
Twitter
Google
Local Auth
Easy Node Authentication: Setup and Local

Resources