To enable Google login, add the app id, app secret and scope property to config/default.json:
{
"authentication": {
"oauth": {
"google": {
"key": "<App ID>",
"secret": "<App Secret>",
"scope": ["openid"]
}
}
}
}According to the documentation of Google: "The scope value must begin with the string openid and then include profile or email or both.".
To also request the email address, add the string "email" to the array of the 'scope' property:
{
"authentication": {
"oauth": {
"google": {
"key": "<App ID>",
"secret": "<App Secret>",
"scope": ["openid", "email"],
"nonce": true
}
}
}
}The property 'nonce', according to the documentation: "A random value generated by your app that enables replay protection.".
The client id (App ID) and secret can be acquired by creating a OAuth client ID:
Important: Fill in the callback url, in a default Feathers setup it will be /oauth/google/callback.
{
"authentication": {
"oauth": {
"facebook": {
"key": "481298021138-hv27glb811ocr7pdon5lsg8hh5a6pgjv.apps.googleusercontent.com",
"secret": "XkWl0witdP4ogeNIgyOi-CeS",
"scope": ["openid", "email"],
"nonce": true
}
}
}
}Note: Use the generated credentials of the OAuth client ID, the key and secret in the example no longer exist.
In src/authentication.js:
const axios = require('axios');
const { OAuthStrategy } = require('@feathersjs/authentication-oauth');
class GoogleStrategy extends OAuthStrategy {
async getEntityData(profile) {
// this will set 'googleId'
const baseData = await super.getEntityData(profile);
// this will grab the picture and email address of the Google profile
return {
...baseData,
profilePicture: profile.picture,
email: profile.email
};
}
}
module.exports = app => {
const authentication = new AuthenticationService(app);
authentication.register('jwt', new JWTStrategy());
authentication.register('local', new LocalStrategy());
authentication.register('google', new GoogleStrategy());
app.use('/authentication', authentication);
app.configure(expressOauth());
};Important: googleId, profilePicture and email are properties that should exist on the database model!


