Skip to content

Instantly share code, notes, and snippets.

@shsunmoonlee
Last active July 23, 2023 11:35
Show Gist options
  • Select an option

  • Save shsunmoonlee/e8cf7328c0c414698ad3db9695ab8cac to your computer and use it in GitHub Desktop.

Select an option

Save shsunmoonlee/e8cf7328c0c414698ad3db9695ab8cac to your computer and use it in GitHub Desktop.
Oauth2 Social login(Facebook, Google) not work on Feathers API backend server, React frontend.
====================
/* backend */
/* app.js */
const path = require('path');
const favicon = require('serve-favicon');
const compress = require('compression');
const cors = require('cors');
const helmet = require('helmet');
const logger = require('winston');
const feathers = require('@feathersjs/feathers');
const configuration = require('@feathersjs/configuration');
const express = require('@feathersjs/express');
const socketio = require('@feathersjs/socketio');
// const sync = require('feathers-sync');
const middleware = require('./middleware');
const services = require('./services');
const appHooks = require('./app.hooks');
const channels = require('./channels');
const authentication = require('./authentication');
const mongodb = require('./mongodb')
const app = express(feathers());
// Load app configuration
app.configure(configuration());
// Enable CORS, security, compression, favicon and body parsing
app.use(cors());
app.use(helmet());
app.use(compress());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(favicon(path.join(app.get('public'), 'favicon.ico')));
// Host the public folder
app.use('/', express.static(app.get('public')));
// Set up Plugins and providers
app.configure(mongodb)
app.configure(express.rest());
app.configure(socketio());
// app.configure(sync({
// db: 'mongodb://localhost:27017/feathers-chat_generated',
// connect: (err) => {
// console.log('mongodb connected');
// }
// }))
// Configure other middleware (see `middleware/index.js`)
app.configure(middleware);
app.configure(authentication);
// Set up our services (see `services/index.js`)
app.configure(services);
// Set up event channels (see channels.js)
app.configure(channels);
// Configure a middleware for 404s and the error handler
app.use(express.notFound());
app.use(express.errorHandler({ logger }));
app.hooks(appHooks);
module.exports = app;
/* users.hooks.js */
const { authenticate } = require('@feathersjs/authentication').hooks;
const { hashPassword, protect } = require('@feathersjs/authentication-local').hooks;
const gravatar = require('../../hooks/gravatar');
function customizeGithubProfile() {
return function(context) {
console.log('Customizing Github Profile');
// If there is a github field they signed up or
// signed in with github so let's pull the primary account email.
if (context.data.github) {
context.data.email = context.data.github.profile.emails.find(email => email.primary).value;
}
// If you want to do something whenever any OAuth
// provider authentication occurs you can do this.
if (context.params.oauth) {
// do something for all OAuth providers
}
if (context.params.oauth.provider === 'github') {
// do something specific to the github provider
}
return Promise.resolve(context);
};
}
function customizeGoogleProfile(){
return function(hook){
console.log('===Hook', hook);
if (hook.data.google) {
console.log('===Customizing Google Profile', hook.data.google);
hook.data.email = hook.data.google.profile.emails
.find(email => email.type==='account').value
}
return Promise.resolve(hook);
}
}
module.exports = {
before: {
all: [],
find: [ authenticate('jwt') ],
get: [ authenticate('jwt') ],
create: [ hashPassword(), gravatar(), customizeGoogleProfile() ],
update: [ hashPassword(), authenticate('jwt'), customizeGoogleProfile() ],
patch: [ hashPassword(), authenticate('jwt') ],
remove: [ authenticate('jwt') ]
},
after: {
all: [
// Make sure the password field is never sent to the client
// Always must be the last hook
protect('password')
],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
},
error: {
all: [],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
}
};
/* config/default.json */
// backend localhost:3030 frontend: localhost:3000
{
"host": "localhost",
"port": 3030,
"public": "../public/",
"paginate": {
"default": 10,
"max": 50
},
"mongodb": "mongodb://localhost:27017/feathers-chat",
"authentication": {
"secret": "secret",
"strategies": [
"jwt",
"local",
"facebook",
"google"
],
"path": "/authentication",
"service": "users",
"jwt": {
"header": {
"typ": "access"
},
"audience": "https://localhost:3030",
"subject": "anonymous",
"issuer": "feathers",
"algorithm": "HS256",
"expiresIn": "1d"
},
"local": {
"entity": "user",
"usernameField": "email",
"passwordField": "password"
},
"facebook": {
"clientID": "my secret",
"clientSecret": "my secret",
"scope": [ "public_profile", "email" ],
"profileFields": [ "id", "displayName", "email", "name", "cover", "picture" ],
"successRedirect": "http://localhost:3000/",
"callbackURL": "http://localhost:3000/auth/facebook/callback"
},
"google": {
"clientID": "my secret",
"clientSecret": "my secret",
"scope": [ "profile openid email" ],
"successRedirect": "http://localhost:3000/",
"callbackURL": "http://localhost:3030/auth/google/callback"
},
"cookie": {
"enabled": true,
"name": "feathers-jwt",
"httpOnly": false,
"secure": false
}
}
}
/* authentication.js */
const authentication = require('@feathersjs/authentication');
const jwt = require('@feathersjs/authentication-jwt');
const local = require('@feathersjs/authentication-local');
const oauth2 = require('@feathersjs/authentication-oauth2');
const GoogleStrategy = require('passport-google-oauth20').Strategy;
const FacebookStrategy = require('passport-facebook').Strategy;
const makeHandler = require('./oauth-handler');
module.exports = function (app) {
const config = app.get('authentication');
const handler = makeHandler(app);
// Set up authentication with the secret
app.configure(authentication(config));
app.configure(jwt());
app.configure(local());
app.configure(oauth2(Object.assign({
name: 'google',
Strategy: GoogleStrategy,
handler: handler(config.google.successRedirect)
}, config.google)));
app.configure(oauth2(Object.assign({
name: 'facebook',
Strategy: FacebookStrategy
}, config.facebook)));
// app.configure(oauth2({
// name: 'facebook',
// Strategy: FacebookStrategy,
// clientID: '<your client id>',
// clientSecret: '<your client secret>',
// scope: ['public_profile', 'email']
// }));
// The `authentication` service is used to create a JWT.
// The before `create` hook registers strategies that can be used
// to create a new valid JWT (e.g. local or oauth2)
app.service('authentication').hooks({
before: {
create: [
authentication.hooks.authenticate(config.strategies)
],
remove: [
authentication.hooks.authenticate('jwt')
]
}
});
};
/* oauth-handler.js */
module.exports = function (app) {
return function (url) {
const config = app.get('authentication');
const options = {
jwt: config.jwt,
secret: config.secret
};
console.log("===redirect url", url)
return function (req, res, next) {
if (req.feathers && req.feathers.payload) {
app.passport.createJWT(req.feathers.payload, options).then(token => {
res.redirect(`${url}?token=${token}`);
})
.catch(error => {
next(error);
});
}
};
};
};
=============
/* frontend */
/* feathers.js */
import io from 'socket.io-client';
// import feathers from '@feathersjs/client';
const feathers = require('@feathersjs/feathers');
const auth = require('@feathersjs/authentication-client');
const socketio = require('@feathersjs/socketio-client');
const socket = io('http://localhost:3030');
const client = feathers();
// client.configure(feathers.hooks())
client.configure(socketio(socket));
// client.configure(feathers.authentication({
// cookie: 'feathers-jwt'
// }))
client.configure(auth({
storage: window.localStorage, cookie: 'feathers-jwt'
}));
// client.configure(auth({
// storage: window.localStorage
// }));
export default client;
/* application.js */
client.authenticate()
.then(response => {
console.log('===Authenticated!', response);
return client.passport.verifyJWT(response.accessToken);
})
.then(payload => {
console.log('===JWT Payload', payload);
console.log("===user_id",payload.userId)
return client.service('users').get(payload.userId);
})
.then(user => {
client.set('===user', user);
})
.catch(error => {
console.error('===Error authenticating!', error);
this.setState({ login: null })
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment