Instantly share code, notes, and snippets.
Last active
July 23, 2023 11:35
-
Star
0
(0)
You must be signed in to star a gist -
Fork
1
(1)
You must be signed in to fork a gist
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ==================== | |
| /* 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