{"_id":"loopback-passport","_rev":"173-d5e96c90dd3d1292294c43ece7fd8d0f","name":"loopback-passport","dist-tags":{"latest":"1.0.2"},"versions":{"0.9.0":{"name":"loopback-passport","version":"0.9.0","keywords":["StrongLoop","LoopBack","social","login","security"],"license":{"url":"https://github.com/strongloop/loopback-passport/blob/master/LICENSE","name":"Dual Artistic-2.0/StrongLoop"},"_id":"loopback-passport@0.9.0","maintainers":[{"name":"rfeng","email":"enjoyjava@gmail.com"}],"homepage":"https://github.com/strongloop/loopback-passport","bugs":{"url":"https://github.com/strongloop/loopback-passport/issues"},"dist":{"shasum":"425f9cbfbc2316e3659cf67ad4302e23ccdd7f13","tarball":"https://registry.npmjs.org/loopback-passport/-/loopback-passport-0.9.0.tgz","integrity":"sha512-H6zqe1PmQP48Llokv6IhKEUdwFg9jEMRqcK2XnX6mWiooiozT8+hdYRXEE/e4M8gtsh6I/twbieaapsHxmd21A==","signatures":[{"sig":"MEUCIQD0mGY/4FEyph+g9G7/9/hx2CyXfOerK6YIA4YBUUIhxAIgeyv0AwyUvRFouHoLqmdRN6vSVXyFGRzBYnGLTAruaPE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"./lib/index.js","_from":".","_shasum":"425f9cbfbc2316e3659cf67ad4302e23ccdd7f13","engines":{"node":">=0.10.0"},"scripts":{"test":"mocha -R spec --timeout 10000 test/*.js"},"_npmUser":{"name":"rfeng","email":"enjoyjava@gmail.com"},"repository":{"url":"git://github.com/strongloop/loopback-passport.git","type":"git"},"_npmVersion":"1.4.9","description":"LoopBack passport integration to support third party logins and account linking","directories":{},"dependencies":{"passport":"~0.2.0"},"devDependencies":{"mocha":"~1.18.2","loopback":"1.x >=1.8.0"},"peerDependencies":{"loopback":"1.x >=1.8.0"}},"1.0.0":{"name":"loopback-passport","version":"1.0.0","keywords":["StrongLoop","LoopBack","social","login","security"],"license":{"url":"https://github.com/strongloop/loopback-passport/blob/master/LICENSE","name":"Dual Artistic-2.0/StrongLoop"},"_id":"loopback-passport@1.0.0","maintainers":[{"name":"rfeng","email":"enjoyjava@gmail.com"},{"name":"ritch","email":"skawful@gmail.com"},{"name":"strongloop","email":"callback@strongloop.com"}],"homepage":"https://github.com/strongloop/loopback-passport","bugs":{"url":"https://github.com/strongloop/loopback-passport/issues"},"dist":{"shasum":"fe9c6264f745898133ad6cebfa9db6851a774e1d","tarball":"https://registry.npmjs.org/loopback-passport/-/loopback-passport-1.0.0.tgz","integrity":"sha512-onCRlP03+BIvUpgot9kWcPjXIZWX8HCh+USgq34OrMv+KcFKYRDitL4Cv67+z/2I9xqnbHvTnuqt8WEkj6SQKA==","signatures":[{"sig":"MEUCIFwEG1gt3C2U8ouvc1BELMe3c+cQ5S24REAi/Y0UOcGEAiEAkFtgFexNOnx3k8Va+3T2Qx+5Phvwz6jA3g7jxv3ZD6I=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"./lib/index.js","_from":".","_shasum":"fe9c6264f745898133ad6cebfa9db6851a774e1d","engines":{"node":">=0.10.0"},"scripts":{"test":"mocha -R spec --timeout 10000 test/*.js"},"_npmUser":{"name":"rfeng","email":"enjoyjava@gmail.com"},"repository":{"url":"git://github.com/strongloop/loopback-passport.git","type":"git"},"_npmVersion":"1.4.9","description":"LoopBack passport integration to support third party logins and account linking","directories":{},"dependencies":{"passport":"~0.2.0"},"devDependencies":{"mocha":"~1.18.2","loopback":"1.x >=1.8.0"},"peerDependencies":{"loopback":"1.x >=1.8.0"}},"1.0.1":{"name":"loopback-passport","version":"1.0.1","keywords":["StrongLoop","LoopBack","social","login","security"],"license":{"url":"https://github.com/strongloop/loopback-passport/blob/master/LICENSE","name":"Dual Artistic-2.0/StrongLoop"},"_id":"loopback-passport@1.0.1","maintainers":[{"name":"rfeng","email":"enjoyjava@gmail.com"},{"name":"ritch","email":"skawful@gmail.com"},{"name":"strongloop","email":"callback@strongloop.com"}],"homepage":"https://github.com/strongloop/loopback-passport","bugs":{"url":"https://github.com/strongloop/loopback-passport/issues"},"dist":{"shasum":"6d19f29fa618f188a96f0bd16503b8660d60b1c7","tarball":"https://registry.npmjs.org/loopback-passport/-/loopback-passport-1.0.1.tgz","integrity":"sha512-0qk3vaC3R89ES0OPoy/K+mZt4uvFpzIIttIFAONwFNkS9RMHlVok35BAdrFjJmsxRQDqIpY2CeQ7r3747C/asA==","signatures":[{"sig":"MEYCIQDl81gk3gkShOIHVsOk/RTqKc5mv7ZCBJX3tmrEjYk6NgIhAMo5E9BVvN5PKIJ+amy9uDQekkswUpcRf6aUAHDs1Wwx","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"./lib/index.js","_from":".","_shasum":"6d19f29fa618f188a96f0bd16503b8660d60b1c7","engines":{"node":">=0.10.0"},"scripts":{"test":"mocha -R spec --timeout 10000 test/*.js"},"_npmUser":{"name":"rfeng","email":"enjoyjava@gmail.com"},"repository":{"url":"git://github.com/strongloop/loopback-passport.git","type":"git"},"_npmVersion":"1.4.9","description":"LoopBack passport integration to support third party logins and account linking","directories":{},"dependencies":{"passport":"~0.2.0"},"devDependencies":{"mocha":"~1.18.2","loopback":"1.x >=1.8.0"},"peerDependencies":{"loopback":"1.x >=1.8.0"}},"1.0.2":{"name":"loopback-passport","version":"1.0.2","keywords":["StrongLoop","LoopBack","social","login","security"],"license":{"url":"https://github.com/strongloop/loopback-passport/blob/master/LICENSE","name":"Dual Artistic-2.0/StrongLoop"},"_id":"loopback-passport@1.0.2","maintainers":[{"name":"rfeng","email":"enjoyjava@gmail.com"},{"name":"ritch","email":"skawful@gmail.com"},{"name":"strongloop","email":"callback@strongloop.com"}],"homepage":"https://github.com/strongloop/loopback-passport","bugs":{"url":"https://github.com/strongloop/loopback-passport/issues"},"dist":{"shasum":"64f471055251abd78ba9ebcd3464771d7bad84e5","tarball":"https://registry.npmjs.org/loopback-passport/-/loopback-passport-1.0.2.tgz","integrity":"sha512-3xwx7DCJfgvYg17R4n2LWd5oN00Ez2HbFfTuOnKRAy+1UNtc8FmAB9MHUnAxBe2G8v4R4d+iZQfDXVy4iOfZPA==","signatures":[{"sig":"MEUCIQDRmrQW04rZe4k9xRBT2deBxRWcBPAm9+OpIAP0vuC3GwIgKPU02Puv+6c1IY5JGxEj8BeTIdIXBqicmLU3Y6Hh504=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"./lib/index.js","_from":".","_shasum":"64f471055251abd78ba9ebcd3464771d7bad84e5","engines":{"node":">=0.10.0"},"scripts":{"test":"mocha -R spec --timeout 10000 test/*.js"},"_npmUser":{"name":"rfeng","email":"enjoyjava@gmail.com"},"repository":{"url":"git://github.com/strongloop/loopback-passport.git","type":"git"},"_npmVersion":"1.4.9","description":"LoopBack passport integration to support third party logins and account linking","directories":{},"dependencies":{"passport":"~0.2.0","underscore":"^1.6.0"},"devDependencies":{"mocha":"~1.18.2","loopback":"1.x >=1.8.0"},"peerDependencies":{"loopback":"2.x || 1.x >=1.8.0"}}},"time":{"created":"2014-05-19T20:25:40.484Z","modified":"2024-07-09T12:43:23.655Z","0.9.0":"2014-05-19T20:25:40.484Z","1.0.0":"2014-05-29T23:18:37.930Z","1.0.1":"2014-05-30T21:49:51.388Z","1.0.2":"2014-06-27T15:56:28.150Z"},"bugs":{"url":"https://github.com/strongloop/loopback-passport/issues"},"license":{"url":"https://github.com/strongloop/loopback-passport/blob/master/LICENSE","name":"Dual Artistic-2.0/StrongLoop"},"homepage":"https://github.com/strongloop/loopback-passport","keywords":["StrongLoop","LoopBack","social","login","security"],"repository":{"url":"git://github.com/strongloop/loopback-passport.git","type":"git"},"description":"LoopBack passport integration to support third party logins and account linking","maintainers":[{"email":"enjoyjava@gmail.com","name":"rfeng"},{"email":"r.m.graham@gmail.com","name":"rmg"},{"email":"dianahmlau@gmail.com","name":"dhmlau"},{"email":"jgorzinski@gmail.com","name":"theprez"},{"email":"oss@bajtos.net","name":"bajtos"},{"email":"skawful@gmail.com","name":"ritch"}],"readme":"# loopback-passport\n\nThe module provides integration between [LoopBack](http://loopback.io) and \n[Passport](http://passportjs.org) to support third party login and account \nlinking for LoopBack applications.\n\n# Use cases\n\n## Third party login\n\nSocial login becomes popular these days as our users don’t want to deal with so \nmany identities. It would be nice to allow the use of a third party provider \nsuch as Facebook, Google, Twitter, or Github to log into LoopBack. The login \nprofiles will be tracked and associated with corresponding LoopBack users. \n\n## Linked accounts\n\nIn LoopBack, most APIs will be built using models that are backed by data \nsources, which in turn uses connectors to interact with other systems or cloud \nservices. Some of the backend systems require user-specific credentials to \naccess the protected resources. For example, an e-commerce engine requires the \nuser credential to see the order history. It’s also true to get pictures from \none or more facebook accounts. One solution to this requirement is to link or \npre-authorize a LoopBack user to other accounts.\n\n# Key components\n\n![Key Components](ids_and_credentials.png)\n\n## UserIdentity model\n\nUserIdentity model keeps track of 3rd party login profiles. Each user identity\nis uniquely identified by provider and externalId. UserIdentity model comes with\na 'belongsTo' relation to the User model.\n\nProperties\n\n- {String} provider: The auth provider name, such as facebook, google, twitter, linkedin\n- {String} authScheme: The auth scheme, such as oAuth, oAuth 2.0, OpenID, OpenID Connect\n- {String} externalId: The provider specific user id\n- {Object} profile: The user profile, see http://passportjs.org/guide/profile\n- {Object} credentials\n  - oAuth: token, tokenSecret\n  - oAuth 2.0: accessToken, refreshToken\n  - OpenID: openId\n  - OpenID Connect: accessToken, refreshToken, profile\n- {*} userId: The LoopBack user id\n- {Date} created: The created date\n- {Date} modified: The last modified date\n\n## UserCredential model\n\nUserCredential has the same set of properties as UserIdentity. It's used to \nstore the credentials from a third party authentication/authorization provider\nto represent the permissions/authorizations from a user from the third party \nsystem. \n\n## ApplicationCredential model\n\nInteracting with third party systems often require some client application level\ncredentials. For example, you will need oAuth 2.0 client id and client secret to \ncall facebook APIs. Such credentials can be supplied from a configuration file \nto your server globally. But if your server accepts API requests from multiple\nclient applications, each client application should have its own credentials. To\nsupport the multi tenancy, this module provides the ApplicationCredential model\nto store credentials associated with a client application.\n\nProperties\n\n- {String} provider: The auth provider name, such as facebook, google, twitter, linkedin\n- {String} authScheme: The auth scheme, such as oAuth, oAuth 2.0, OpenID, OpenID Connect\n- {Object} credentials: The provider specific credentials\n  - openId: {returnURL: String, realm: String}\n  - oAuth2: {clientID: String, clientSecret: String, callbackURL: String}\n  - oAuth: {consumerKey: String, consumerSecret: String, callbackURL: String}\n- {Date} created: The created date\n- {Date} modified: The last modified date\n\nApplicationCredential model comes with a 'belongsTo' relation to the Application \nmodel.\n\n## PassportConfigurator\n\nPassportConfigurator is the bridge between LoopBack and Passport. \n\n- set up models with LoopBack\n- initialize passport\n- create Passport strategies from provider configurations\n- set up routes for auth and callback \n\n# Flows\n\n## Third party login flow\n\nThe following steps use Facebook oAuth 2.0 login as an example.\n\n1. A visitor requests to log in using Facebook (or other providers), typically \nby clicking on a link or button backed by LoopBack to kick off oAuth 2.0 \nauthorization code flow\n2. LoopBack redirects the browser to Facebook's authorization endpoint so that\nthe user can log into Facebook and grant permissions to LoopBack\n3. Facebook redirects the browser to a callback URL hosted by LoopBack \nwith the oAuth 2.0 authorization code\n4. LoopBack makes a request to the Facebook token endpoint to get an access \ntoken using the authorization code \n5. LoopBack uses the access token to retrieve the user's Facebook profile\n6. LoopBack searches the UserIdentity model by (provider, externalId) to see \nthere is an existing LoopBack user for the given Facebook id\n7. If yes, set the LoopBack user to the current context\n8. If not, create a LoopBack user from the profile and create a corresponding \nrecord in UserIdentity to track the 3rd party login. Set the newly created user \nto the current context.\n\n## Third party account linking flow\n\nThe following steps use Facebook oAuth 2.0 login as an example.\n\n1. The user log into LoopBack first directly or through third party login\n2. The user clicks on a link or button by LoopBack to kick off oAuth 2.0 \nauthorization code flow so that the user can grant permissions to LoopBack\n3. Perform the same steps 2-5 as third party login \n4. LoopBack searches the UserCredential model by (provider, externalId) to see \n   there is an existing LoopBack user for the given Facebook id\n5. Link the Facebook account to the current user by creating a record in the\nUserCredential model to store the Facebook credentials, such as access token\n6. Now the LoopBack user wants to get a list of pictures from the linked Facebook\naccount(s). LoopBack can look up the Facebook credentials associated with the \ncurrent user and use them to call Facebook APIs to retrieve the pictures. \n\n# Use the module with a LoopBack application\n\nA demo application is built with this module to showcase how to use the APIs \nwith a LoopBack application. The code is available at:\n\n[https://github.com/strongloop-community/loopback-example-passport](https://github.com/strongloop-community/loopback-example-passport)\n\n## Configure third party providers\n\nThe following example shows two providers: facebook-login for login with \nfacebook and google-link for linking your google accounts with the current \nLoopBack user.\n\n```json\n{\n  \"facebook-login\": {\n    \"provider\": \"facebook\",\n    \"module\": \"passport-facebook\",\n    \"clientID\": \"{facebook-client-id-1}\",\n    \"clientSecret\": \"{facebook-client-secret-1}\",\n    \"callbackURL\": \"http://localhost:3000/auth/facebook/callback\",\n    \"authPath\": \"/auth/facebook\",\n    \"callbackPath\": \"/auth/facebook/callback\",\n    \"successRedirect\": \"/auth/account\",\n    \"scope\": [\"email\"]\n  },\n  ...\n  \"google-link\": {\n    \"provider\": \"google\",\n    \"module\": \"passport-google-oauth\",\n    \"strategy\": \"OAuth2Strategy\",\n    \"clientID\": \"{google-client-id-2}\",\n    \"clientSecret\": \"{google-client-secret-2}\",\n    \"callbackURL\": \"http://localhost:3000/link/google/callback\",\n    \"authPath\": \"/link/google\",\n    \"callbackPath\": \"/link/google/callback\",\n    \"successRedirect\": \"/link/account\",\n    \"scope\": [\"email\", \"profile\"],\n    \"link\": true\n  }\n}\n```\n\n**NOTE**\n\nYou'll need to register with facebook and google to get your own client id and \nclient secret.\n\n- Facebook: https://developers.facebook.com/apps\n- Google: https://console.developers.google.com/project\n\n## Add code snippets to app.js\n\n```js\nvar loopback = require('loopback');\nvar path = require('path');\nvar app = module.exports = loopback();\n\n// Create an instance of PassportConfigurator with the app instance\nvar PassportConfigurator = require('loopback-passport').PassportConfigurator;\nvar passportConfigurator = new PassportConfigurator(app);\n\napp.boot(__dirname);\n\n...\n\n// Enable http session\napp.use(loopback.session({ secret: 'keyboard cat' }));\n\n// Load the provider configurations\nvar config = {};\ntry {\n  config = require('./providers.json');\n} catch(err) {\n  console.error('Please configure your passport strategy in `providers.json`.');\n  console.error('Copy `providers.json.template` to `providers.json` and replace the clientID/clientSecret values with your own.');\n  process.exit(1);\n}\n\n// Initialize passport\npassportConfigurator.init();\n\n// Set up related models\npassportConfigurator.setupModels({\n  userModel: app.models.user,\n  userIdentityModel: app.models.userIdentity,\n  userCredentialModel: app.models.userCredential\n});\n\n// Configure passport strategies for third party auth providers\nfor(var s in config) {\n  var c = config[s];\n  c.session = c.session !== false;\n  passportConfigurator.configureProvider(s, c);\n}\n```","readmeFilename":"README.md","users":{"canercandan":true,"arnold-almeida":true}}