I am using the passport-facebook plugin in a NextJS app and my test script defines the strategy as below:
// Configure Passport
// ---------------------------------------------------------------
passport.use(new LocalStrategy(User.authenticate()));
passport.use(new FacebookStrategy({
clientID: process.env.FACEBOOK_APP_ID,
clientSecret: process.env.FACEBOOK_APP_SECRET,
callbackURL: process.env.FACEBOOK_APP_CALLBACK,
},
function (accessToken, refreshToken, profile, done) {
console.log(profile);
}
));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
// ---------------------------------------------------------------
My authentication routes are:
// Facebook
router.get('/auth/facebook', passport.authenticate('facebook'));
router.get('/facebook/callback',
passport.authenticate('facebook', {
successRedirect: '/success',
failureRedirect: '/failure',
}),
);
All I'm trying to do with this for now, is to display all the values returned by Facebook upon a successful authentication. The authentication works as expected but Facebook seems to be returning undefined for most keys in the profile object:
{ id: '1234567812345677',
username: undefined,
displayName: 'John Doe',
name:
{ familyName: undefined,
givenName: undefined,
middleName: undefined },
gender: undefined,
profileUrl: undefined,
provider: 'facebook',
_raw: '{"name":"John Doe","id":"1234567812345677"}',
_json: { name: 'John Doe', id: '1234567812345677' } }
All I get is the displayName and id; everything else is undefined. What's going wrong? A very similar question was asked here before but none of the answers (no accepted answer) offered address the problem.
I have no experience in this area, but from looking at the readme of facebook-passport, it sounds like you need to use the profileFields in your FacebookStrategy. :
The Facebook profile contains a lot of information about a user. By
default, not all the fields in a profile are returned. The fields
needed by an application can be indicated by setting the profileFields
option.
new FacebookStrategy({
clientID: FACEBOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: "http://localhost:3000/auth/facebook/callback",
profileFields: ['id', 'displayName', 'photos', 'email']
}), ...)
Refer to the User section of the Graph API Reference for the complete
set of available fields.
Related
I'm trying to exchange the authorization code I got in the first step of the documentation for access token. Where I'm stuck is how to send a request for the token that contains the code I've just got with the first request.
This is my code:
auth: {
redirect: {
login: '/',
callback: '/auth'
},
strategies: {
wrike: {
scheme: 'oauth2',
endpoints: {
authorization: 'https://login.wrike.com/oauth2/authorize/v4',
token: 'https://login.wrike.com/oauth2/token',
logout: '/'
},
token: {
property: 'access_token',
type: 'Bearer',
maxAge: 1800
},
responseType: 'code',
grantType: 'authorization_code',
accessType: 'offline',
clientId: XXXX,
client_secret: YYYY
}
}
}
I can't figure it out how I should set up the redirect URI, in the client or in the server side? How should I do the second request? (This below)
POST https://login.wrike.com/oauth2/token
//Parameters:
client_id=<client_id>
client_secret=<client_secret>
grant_type=authorization_code
code=<authorization_code>
I think Edward is right. It doesn't seem to work. You can either do the custom schema which is what I am going to do, or you can do what I currently have which is something like this (of course ignore all the console.log and stuff like that):
const urlParams = new URLSearchParams(window.location.search)
const code = urlParams.get('code')
const state = urlParams.get('state')
console.log('state', state)
console.log('stateStorage', window.localStorage.getItem(state))
if ((code && state) && state === window.localStorage.getItem('state')) {
this.$axios.post('http://publisher-local.co.uk:8080/oauth/token', {
grant_type: 'authorization_code',
client_id: 5,
redirect_uri: 'http://localhost:3000/auth',
code_verifier: window.localStorage.getItem('verifier'),
code
}).then(response => {
this.$auth.setUserToken(response.data.access_token)
this.$auth.fetchUser()
})
}
So basically after you are redirected back to your client after logging in on the server page just look for the details in the URL and make the request yourself.
I have this Facebook strategy:
facebook: {
access_token_endpoint: 'http://***.**/api/v0/auth/social',
access_type: 'offline',
client_id: '*******',
grant_type: 'authorization_code',
redirect_uri: socialLoginUrl + '/account/aanmelden',
response_type: 'code',
token_key: 'jwt',
userinfo_endpoint: 'https://****.***.**/user/profile'
},
When I try to register with Facebook I get the following form in the request:
code: **
client_id: **
redirect_uri: **
response_type: **
grant_type: **
I want to supply some data to the back-end when I register:
"attributes":{
"code":"*****",
"vendor":"Facebook"
},
How do I add this to the form that's being sent to the access_token_endpoint ?
// updated question.
Calling the loginWith function:
#click="$auth.loginWith('facebook', { params: data })"
data object:
data () {
return {
data: {
type: 'user',
attributes: {
vendor: 'Facebook',
code: '**'
}
},
}
},
Request payload in the browser:
code=**&client_id=**&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Faccount%2Faanmelden&response_type=code&grant_type=authorization_code
Response from the back-end:
I expect the data object to be available in the payload, but I'm not sure if I'm doing this correctly.
From the official docs, it looks like you can do
this.$auth.loginWith('facebook', { params: { /* additional authentication parameters */ } })
.then(() => this.$toast.success('Logged In!'))
I never used it with Facebook but it's working great with local (using JWT).
The related part of the documentation: https://auth.nuxtjs.org/api/auth#loginwithstrategyname-args
I am trying to connect actual bank accounts to the stripe accounts in Stripe Connect.
However, I am struggling with the actual implementation.
I use Custom Accounts, so I want to provide the user with the account creation logic through my iOS app.
In the Stripe API Reference it says that the recommended way to accomplish this is:
"Destination accounts are added via the external_accounts parameter when creating or updating Custom accounts. The value should be a bank account or debit card token returned from Stripe.js."
Creating the token is documented as follows (I am using NodeJS):
stripe.createToken('bank_account', {
country: 'US',
currency: 'usd',
routing_number: '110000000',
account_number: '000123456789',
account_holder_name: 'Jenny Rosen',
account_holder_type: 'individual',
}).then(function(result) {
// Handle result.error or result.token
});
Where to I link that token in the account creation process? See related code below:
app.post('/create_account', (req, res) => {
console.log('create account called');
var email = req.body.email;
var firstname = req.body.firstname;
var lastname = req.body.lastname;
stripe.accounts.create({
country: "CH",
type: "custom",
email: email,
business_name: "examplename",
legal_entity: {
first_name: "firstname",
last_name: "lastname",
dob: {
day: 1,
month: 1,
year: 1900
}
}
}).then((account) => {
res.status(200).send(account)
}).catch((err) => {
console.log(err, req.body)
res.status(500).end()
});
});
Is the token creation just a means of validating the account information client-side?
Would be glad if someone can elaborate on this with a simple step-by-step explanation, thank you in advance!
You'd pass the token in the external_account parameter:
var bankAccountToken = req.body.stripeToken;
stripe.accounts.create({
country: "CH",
type: "custom",
// ...
external_account: bankAccountToken,
}).then((account) => {
// ...
I'm struggling to get the email address of twitter users when they login
I get the following error from Joi "Error: Uncaught error: Invalid options value: must be true, falsy or an object"
server.auth.strategy('twitter', 'bell', {
provider: 'twitter',
scope: ['public_profile', 'email'],
config: {
extendedProfile: true,
getParams: 'include_email',
getMethod: 'account/verify'
},
password: config.longpass, //Use something more secure in production
clientId: config.twitter_key,
clientSecret: config.twitter_secret,
isSecure: config.useHttps //Should be set to true (which is the default) in production
});
This code works for me.
server.auth.strategy('twitter', 'bell', {
provider: 'twitter',
config: {
getMethod: 'account/verify_credentials',
getParams: {include_email:'true' },//doesn't work without quotes!
},
password: 'secret_cookie_encryption_password', //Use something more secure in production
clientId: secret.twitterId,
clientSecret: secret.twitterSecret,
isSecure: false //Should be set to true (which is the default) in production
});
Don't forget to allow necessary permission (Request email addresses from users) in your Twitter application settings.
I'm trying to use Google's 'google-api-nodejs-client' package (https://github.com/google/google-api-nodejs-client) to handle OAuth 2.0 authentication.
I've modified the example in examples/oauth2.js to console.log the entire profile object.
What scope can I use to correctly extract users' 'givenName' and 'familyName' if they're authenticating using a Google Apps account? Using the following scope:
scope: [
'https://www.googleapis.com/auth/plus.login',
'https://www.googleapis.com/auth/plus.profile.emails.read'
]
returns the following response once authenticated:
{ kind: 'plus#person',
etag: '"LONG STRING"',
emails: [ { value: 'example#example.example', type: 'account' } ],
objectType: 'person',
id: '123456',
displayName: '',
name: { familyName: '', givenName: '' },
image:
{ url: 'https://lh3.googleusercontent.com/ etc etc',
isDefault: false },
isPlusUser: false,
language: 'en_GB',
circledByCount: 0,
verified: false,
domain: 'example.example' }
I tried fooling around with the API on the API Explorer (https://developers.google.com/apis-explorer/#p/plus/v1/plus.people.get?userId=me) and only needed the 'https://www.googleapis.com/auth/plus.login' scope to get my familyName and givenName.
Perhaps the user that you are requesting the data from does not have a given and family name set?