Using Oauth 2.0 with Next js - oauth-2.0

I want to use Google OAuth 2.0 with my React/Next.js app. I've set up my OAuth Client IDs on the Google Developer console, and set up a route in my server.js node file. When I try to GET request https://localhost:3000/auth/google I get the Next js 404 Not Found page. It's obviously looking for a page called auth in my Next js pages directory. Tried using the next/Router, wrapping my button in an anchor element, fetch API GET requesting https://localhost:3000/auth/google, all failed.
I've managed to successfully implement passport user authentication, salting, hashing and sessions but it's just the Oauth that's giving me trouble.
If it were a standard node application https://localhost:3000/auth/google would redirect to the interface where users could login with their google credentials.
I've tried search the nextjs examples github for implementations of oauth but there doesn't seem to be any. Anyone know how I can use OAuth 2.0 with Next JS?
Route
server.get("/auth/google", (req, res) =>{
passport.authenticate("google", { scope: ['profile']});
})
Button that's supposed to take me to the google login/register page
<button className="btn btn-block btn-social btn-google" style={{'color': '#fff'}} onClick={() => Router.push("/auth/google")}>
<FontAwesomeIcon icon={faGoogle} className="google-social-button" /> Sign Up with Google
</button>

You can simply try this,
const app = next({ dev });
const server = express()
server.get('/auth/google/callback*',
passport.authenticate('google'),
(req, res) => {
res.redirect('/dashboard');
});
server.get('/auth/google*', (req, res) => {
return app.render(req, res, req.path, req.query)
});
server.get('/api/logout', (req, res) => {
req.logout();
res.send(req.user);
})
server.get('/api/current_user', (req, res) => {
res.send(req.user);
});
server.get('*', (req, res) => {
return handle(req, res)
});
Just make sure the google reqs are above the server.get('*') route as it catches all requests.
More help: https://github.com/zeit/next.js/blob/canary/examples/custom-server-express/server.js

Not sure if you're still looking for an answer here, but if are, you can do something like the following under the latest Next.js version (9+), https://nextjs.org/blog/next-9#api-routes
//--- PART 1: DEFINE YOUR GOOGLE OAUTH STRATEGY ALA PASSPORT
// This would be in its own passport.js file (the filename doesn't matter), the key thing being that you define your Google Strategy
import passport from 'passport'
import {
Strategy as GoogleStrategy,
} from 'passport-google-oauth20'
passport.use(new GoogleStrategy({
...getGoogleKeySecret(), // a utility for grabbing your secret keys
callbackURL: `/api/authorize/google/callback`,
passReqToCallback: true, // http://www.passportjs.org/docs/authorize/
}, async function(req, accessToken, refreshToken, profile, done) {
// Do any user lookup/mapping you need here
return done(null, profile)
}))
//--- PART 2: DEFINE THE END-POINT
// This would be in your pages/api/auth/google.js file
import nextConnect from 'next-connect'
import middleware from '../any/custom/middleware/stuff/you/may/have'
const handler = nextConnect()
handler.use(middleware)
handler.get(passport.authenticate("google", {
scope: ['profile', 'email', 'openid'], // tailer the scope to fit your needs
}))
export default handler
To try it out, direct a user to /api/auth/google via your UI or hit the URL directly, and you should be taken through the Google OAuth 2.0 flow.
Hope this helps - good luck!

Related

I am getting a 403 error when trying to implement OAuth 1.0a with twitter API

i am trying to generate a OAuth 1.0a link with twitter api in JS using the twitter-api-v2
const client = new TwitterApi({ appKey: process.env.API_KEY, appSecret: process.env.API_KEY_SECRET });
app.listen(3000, () => console.log("You used express to set up a server!"));
app.get("/callback", (req, res) => {
console.log(req);
});
const authLink = await client.generateAuthLink("localhost:3000/callback");
i have checked my credentials, and have setup OAuth 1.0a on the twitter developer portal.
Turns out, i made a mistake, and just needed to edit the URL in my twitter developer portal.

React Component Logging in with Authorization Code Grant and Amplify/Cognito hosted UI

I'm successfully using the Cognito federated sign in with the hosted ui in my react app. This login flow redirects to a login url in my application. My intent is to fetch the Auth.currentAuthenticatedUser() in a useEffect hook when the auth_code appears on the request (for now just looking to see if the search component has any value) and then to redirect to another route.
The problem I'm having is that the https://foo-api.auth.us-east-1.amazoncognito.com/oauth2/token call that Amplify makes behind the scenes doesn't return until after the Auth.currentAuthenticatedUser promise resolves with a failure.
My naive workaround/solution was to wrap that call in a timer, see below. This works fine, but seems brittle and wrong-headed (even if I handle the possibility of infinite calls).
import React, { useEffect } from "react";
import {useLocation, useHistory} from "react-router-dom"
import Auth from "#aws-amplify/auth";
import { CognitoHostedUIIdentityProvider } from "#aws-amplify/auth/lib-esm/types";
const App = () => {
useAuthentication();
function useAuthentication() {
const location = useLocation()
const history = useHistory()
useEffect(_ => {
if(location.search) {
const interval = setInterval(() => {
Auth.currentAuthenticatedUser()
.then(_=> history.push('/'))
.catch(console.log)
}, 1000)
return _ => clearInterval(interval)
}
}, [location]);
}
return (
<div className="App">
<button
type="button"
onClick={() =>
Auth.federatedSignIn({
provider: CognitoHostedUIIdentityProvider.Cognito
})
}
>
Federated sign in
</button>
</div>
);
};
export default App;
This seems almost like an Amplify bug, at least when I'm trying to use it like this. I see that this issue comes up here: AWS Cognito hosted UI and Amplify Auth with authorization code OAuth flow. But I'm not using any other Amplify components like Hub.
Is there a better, more idiomatic way to handle this situation?

Autodesk-forge viewer: Access token

I was following forge tutorials to embed the forge viewer in an html page.
I ended up at this forge-made page, link: https://autodesk-forge.github.io/forge-tutorial-postman/display_svf.html
I understand how to retrieve an access token using cURL however I would like to modify that website so that I don't have to enter the access token myself.
I would like the access-token from the cURL response to be automatically imported as the access token for that website. How is this possible.
The code for the webpage is here: https://github.com/Autodesk-Forge/forge-tutorial-postman/blob/master/docs/display_svf.html
How can I add a function/method to automatically retrieve an access token when I hit submit on the webpage.
Any help is much appeciated!
Cheers!
The server side code you are looking for is:
app.get('/api/forge/oauth', function (req, res) {
Axios({
method: 'POST',
url: 'https://developer.api.autodesk.com/authentication/v1/authenticate',
headers: {
'content-type': 'application/x-www-form-urlencoded',
},
data: querystring.stringify({
client_id: FORGE_CLIENT_ID,
client_secret: FORGE_CLIENT_SECRET,
grant_type: 'client_credentials',
scope: scopes
})
})
.then(function (response) {
// Success
access_token = response.data.access_token;
console.log(response);
res.send('<p>Authentication success!</p>');
})
.catch(function (error) {
// Failed
console.log(error);
res.send('Failed to authenticate');
});
});
Please refer the Forge 2-Legged Authentication tutorials for the code and more details. We also have more tutorials and workflow on Learn Autodesk Forge.

How to create SendBird user with SendBird Platform API and Request node library

We are building a react-native chat app. We are implementing a back end authentication solution on google Firebase. The creation of a new user in Firebase Auth triggers a cloud function which should create a new SendBird user with an access token. The access token will be stored in Cloud Firestore, ready for retrieval the next time the user logs in.
We are having trouble implementing the POST request that creates the new user via the platform API. We are using the Request library for node.js. We are able to reach the API endpoint, but the following object is returned: { message: 'SendBird API Endpoint.', error: true }. There is no indication of what the error may be.
This happens when sending the request to the base url. When we send the request to /users or /v3/users, we receive a 403 error.
Any indication as to what may be causing this problem would be greatly appreciated.
Below is the cloud function index.js code
const functions = require('firebase-functions');
const admin = require("firebase-admin");
const request = require('request');
admin.initializeApp();
exports.handleNewUser = functions.auth.user().onCreate((user) => {
var newUserRequestBody = {
"user_id": user.email,
"nickname": user.email,
"profile_url": "",
"issue_access_token": true,
}
request.post({
headers: {
'Content-Type': 'application/json, charset=utf8',
'Api-Token': // API Token
},
url: 'https://api-{application_id}.sendbird.com',
form: newUserRequestBody
}, function(error, response, body){
if (!error && response.statusCode === 200) {
const info = JSON.parse(body);
console.log("request successful");
console.log(response.statusCode);
console.log(info);
}
else{
console.log("request unsuccessful");
console.log(response.statusCode);
console.log(error);
}
});
return null;
});
Did you try with full path of end point to url: (including /v3/users)?
Or you may need to use "baseUrl" like below?
https://github.com/request/request#requestoptions-callback
Also, you need to make sure that you correctly used {application_id} value and {API Token} value.
You can double check this from your dashboard of SendBird.
http://dashboard.sendbird.com > Log in with your ID > select your APP.
There is a section named "App credentials" in "Overview" menu.
You can double check your API-request URL and API-Token value from there.

How to integrate OAuth2.0 login in electron

I am newbie to electron and I am currently trying to implement an OAuth2.0 API which requires a callback URI. Url callback requires valid URL (https://myserver.com/sucess). so i tried this code snippet but does not work.
// Your GitHub Applications Credentials
var options = {
client_id: 'your_client_id',
client_secret: 'your_client_secret',
scopes: ["user:email", "notifications"] // Scopes limit access for OAuth tokens.
};
app.on('ready', () => {
// Build the OAuth consent page URL
var authWindow = new BrowserWindow({ width: 800, height: 600, show: false, 'node-integration': false });
var githubUrl = 'https://github.com/login/oauth/authorize?';
var authUrl = githubUrl + 'client_id=' + options.client_id + '&scope=' + options.scopes;
authWindow.loadURL(authUrl);
authWindow.show();
function handleCallback (url) {
console.log(url);
}
// Handle the response from GitHub - See Update from 4/12/2015
authWindow.webContents.on('will-navigate', function (event, url) {
handleCallback(url);
});
authWindow.webContents.on('did-get-redirect-request', function (event, oldUrl, newUrl) {
handleCallback(newUrl);
});
// Reset the authWindow on close
authWindow.on('close', function() {
authWindow = null;
}, false);
});
also, i used angular js route but does not work either.
so I'm wondering if there is a way to run server inside electron app to serve app from URL (https://localhost:3000) and if so how this will affect app behavior at packaging and distributing time, i means does the app will run from the same port
... any suggestions will help about how i can approach this problem. thank you
I had the same issue last week, i needed to integrate my electron app with vkontakte api which uses form of OAuth protocol. What you can do:
1) You launch local node http server, probably in separate process as i did.
2) You request code through oauth link and set redirect uri as http://127.0.0.1:8000/, for some reason https://localhost didn't work for me.
3) In main process you wait for message with code from server, on server implemented corresponding logic (when you receive request and code in it send through process.send back to parent message with code)
4)You request access token from main process, you shouldn't change redirect_uri. You again catch response from your server.
5) You get access_token, you kill server...
But when i did all this i read their docs till end and there was stated that standalone apps, like mine for desktop could receive token in easier way through "implicit flow", and you can get your token with only one call. Hope my experience could be extrapolated on your issue. Good luck!

Resources