Parse Server supports 3rd party authentication with
- Apple
- Github
- Janrain Capture
- Janrain Engage
- Keycloak
- LDAP
- Meetup
- Microsoft Graph
- PhantAuth
- Spotify
- vKontakte
Configuration options for these 3rd-party modules is done with the auth option passed to Parse Server:
{
auth: {
twitter: {
consumer_key: "", // REQUIRED
consumer_secret: "" // REQUIRED
},
facebook: {
appIds: "FACEBOOK APP ID"
}
}
}Below, you will find all expected payloads for logging in with a 3rd party auth.
Note, most of them don't require a server configuration so you can use them directly, without particular server configuration.
{
"facebook": {
"id": "user's Facebook id number as a string",
"access_token": "an authorized Facebook access token for the user",
"expiration_date": "token expiration date of the format: yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
}
}Learn more about Facebook login.
{
"twitter": {
"id": "user's Twitter id number as a string",
"consumer_key": "your application's consumer key",
"consumer_secret": "your application's consumer secret",
"auth_token": "an authorized Twitter token for the user with your application",
"auth_token_secret": "the secret associated with the auth_token"
}
}The options passed to Parse server:
{
auth: {
twitter: {
consumer_key: "", // REQUIRED
consumer_secret: "" // REQUIRED
},
}
}Learn more about Twitter login.
{
"anonymous": {
"id": "random UUID with lowercase hexadecimal digits"
}
}As of Parse Server 3.5.0 you can use Sign In With Apple.
{
"apple": {
"id": "user",
"token": "the identity token for the user"
}
}Using Apple Sign In on a iOS device will give you a ASAuthorizationAppleIDCredential.user string for the user identifier, which can be match the sub component of the JWT identity token.
Using Apple Sign In through the Apple JS SDK or through the REST service will only give you the JWT identity token (id_token) which you'll have to decompose to obtain the user identifier in its sub component. As an example you could use something like JSON.parse(atob(token.split(".")[1])).sub.
{
auth: {
apple: {
client_id: "", // optional (for extra validation), use the Service ID from Apple.
},
}
}Learn more about Sign In With Apple.
{
"github": {
"id": "user's Github id (string)",
"access_token": "an authorized Github access token for the user"
}
}Google oauth supports validation of id_token's and access_token's.
{
"google": {
"id": "user's Google id (string)",
"id_token": "an authorized Google id_token for the user (use when not using access_token)",
"access_token": "an authorized Google access_token for the user (use when not using id_token)"
}
}{
"instagram": {
"id": "user's Instagram id (string)",
"access_token": "an authorized Instagram access token for the user",
"apiURL": "an api url to make requests. Default: https://api.instagram.com/v1/"
}
}{
"keycloak": {
"access_token": "access token from keycloak JS client authentication",
"id": "the id retrieved from client authentication in Keycloak",
"roles": ["the roles retrieved from client authentication in Keycloak"],
"groups": ["the groups retrieved from client authentication in Keycloak"]
}
}The authentication module will test if the authData is the same as the userinfo oauth call, by comparing the attributes.
Copy the JSON config file generated on Keycloak (tutorial)
and paste it inside of a folder (Ex.: auth/keycloak.json) in your server.
The options passed to Parse Server:
{
auth: {
keycloak: {
config: require(`./auth/keycloak.json`) // Required
}
}
}The LDAP module can check if a
user can authenticate (bind) with the given credentials. Optionally, it can also check if the user is in a certain group.
This check is done using a user specified query, called an LDAP Filter.
The query should return all groups which the user is a member of. The cn attribute of the query results is compared to groupCn.
To build a query which works with your LDAP server, you can use a LDAP client like Apache Directory Studio.
{
"ldap": {
"url": "ldap://host:port",
"suffix": "the root of your LDAP tree",
"dn": "Bind dn. {{id}} is replaced with the id suppied in authData",
"groupCn": "Optional. A group which the user must be a member of.",
"groupFilter": "Optional. An LDAP filter for finding groups which the user is part of. {{id}} is replaced with the id supplied in authData."
}
}If either groupCN or groupFilter is not specified, the group check is not performed.
Example Configuration (this works with the public LDAP test server hosted by Forumsys):
{
"ldap": {
"url": "ldap://ldap.forumsys.com:389",
"suffix": "dc=example,dc=com",
"dn": "uid={{id}}, dc=example, dc=com",
"groupCn": "Chemists",
"groupFilter": "(&(uniqueMember=uid={{id}},dc=example,dc=com)(objectClass=groupOfUniqueNames))"
}
}authData:
{
"authData": {
"ldap": {
"id": "user id",
"password": "password"
}
}
}{
"linkedin": {
"id": "user's LinkedIn id (string)",
"access_token": "an authorized LinkedIn access token for the user",
"is_mobile_sdk": true|false // set to true if you acquired the token through LinkedIn mobile SDK
}
}{
"meetup": {
"id": "user's Meetup id (string)",
"access_token": "an authorized Meetup access token for the user"
}
}{
"microsoft": {
"id": "user's microsoft id (string)", // required
"access_token": "an authorized microsoft graph access token for the user", // required
"mail": "user's microsoft email (string)"
}
}Learn more about Microsoft Graph Auth Overview.
To get access on behalf of a user.
As of Parse Server 3.7.0 you can use PhantAuth.
{
"phantauth": {
"id": "user's PhantAuth sub (string)",
"access_token": "an authorized PhantAuth access token for the user",
}
}Learn more about PhantAuth.
{
"qq": {
"id": "user's QQ id (string)",
"access_token": "an authorized QQ access token for the user"
}
}{
"spotify": {
"id": "user's spotify id (string)",
"access_token": "an authorized spotify access token for the user"
}
}{
"vkontakte": {
"id": "user's vkontakte id (string)",
"access_token": "an authorized vkontakte access token for the user"
}
}{
auth: {
vkontakte: {
appSecret: "", // REQUIRED, your vkontakte application secret
appIds: "" // REQUIRED, your vkontakte application id
},
}
}{
"wechat": {
"id": "user's wechat id (string)",
"access_token": "an authorized wechat access token for the user"
}
}{
"weibo": {
"id": "user's weibo id (string)",
"access_token": "an authorized weibo access token for the user"
}
}It is possible to leverage the OAuth support with any 3rd party authentication that you bring in.
{
auth: {
my_custom_auth: {
module: "PATH_TO_MODULE" // OR object,
option1: "",
option2: "",
}
}
}On this module, you need to implement and export those two functions validateAuthData(authData, options) {} and validateAppId(appIds, authData, options) {}.
For more information about custom auth please see the examples:
It is also possible to use a completely external, JWT-based authentication mechanism.
Simply inject middleware before Parse Server:
const authenticateUser = (req, res, next) => {
const jwtPayload = verifyJwt(token);
req.userFromJWT = new Parse.User({
objectId: jwtPayload.parseUserId,
role: jwtPayload.parseRole,
username: jwtPayload.parseUserName,
department: jwtPayload.parseDepartment,
email: jwtPayload.email
});
return next();
};
Application.use('/parse', authenticateUser, new ParseServer({...}));Clients can leverage this new functionality with trivial changes.
// This included our tokens in the 'Authorization' header as a bearer token
Parse.serverAuthType = 'Bearer';
Parse.serverAuthToken = `${getJwt()}`;
// No no longer any need for user password,
// because authentication is provided by bearer token
Parse.User.logIn(username, '').then(parseUser => ...);