Advertisement
Guest User

Untitled

a guest
Jul 8th, 2016
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 49.79 KB | None | 0 0
  1.  
  2. Search for Strategies
  3. 8,192
  4. by Jared Hanson
  5. Home
  6. Documentation
  7. Features
  8. Strategies
  9. Supported by
  10. GENERAL
  11. Overview
  12. Authenticate
  13. Configure
  14. Username & Password
  15. OpenID
  16. OAuth
  17. User Profile
  18. PROVIDERS
  19. APIS
  20. OPERATIONS
  21. Overview
  22.  
  23. Passport is authentication middleware for Node. It is designed to serve a singular purpose: authenticate requests. When writing modules, encapsulation is a virtue, so Passport delegates all other functionality to the application. This separation of concerns keeps code clean and maintainable, and makes Passport extremely easy to integrate into an application.
  24.  
  25. In modern web applications, authentication can take a variety of forms. Traditionally, users log in by providing a username and password. With the rise of social networking, single sign-on using an OAuth provider such as Facebook or Twitter has become a popular authentication method. Services that expose an API often require token-based credentials to protect access.
  26.  
  27. Passport recognizes that each application has unique authentication requirements. Authentication mechanisms, known as strategies, are packaged as individual modules. Applications can choose which strategies to employ, without creating unnecessary dependencies.
  28.  
  29. Despite the complexities involved in authentication, code does not have to be complicated.
  30.  
  31. app.post('/login', passport.authenticate('local', { successRedirect: '/',
  32. failureRedirect: '/login' }));
  33. Install
  34.  
  35. $ npm install passport
  36. Authenticate
  37.  
  38. Authenticating requests is as simple as calling passport.authenticate() and specifying which strategy to employ. authenticate()'s function signature is standard Connect middleware, which makes it convenient to use as route middleware in Express applications.
  39.  
  40. app.post('/login',
  41. passport.authenticate('local'),
  42. function(req, res) {
  43. // If this function gets called, authentication was successful.
  44. // `req.user` contains the authenticated user.
  45. res.redirect('/users/' + req.user.username);
  46. });
  47. By default, if authentication fails, Passport will respond with a 401 Unauthorized status, and any additional route handlers will not be invoked. If authentication succeeds, the next handler will be invoked and the req.user property will be set to the authenticated user.
  48.  
  49. Note: Strategies must be configured prior to using them in a route. Continue reading the chapter on configuration for details.
  50.  
  51. Redirects
  52.  
  53. A redirect is commonly issued after authenticating a request.
  54.  
  55. app.post('/login',
  56. passport.authenticate('local', { successRedirect: '/',
  57. failureRedirect: '/login' }));
  58. In this case, the redirect options override the default behavior. Upon successful authentication, the user will be redirected to the home page. If authentication fails, the user will be redirected back to the login page for another attempt.
  59.  
  60. Flash Messages
  61.  
  62. Redirects are often combined with flash messages in order to display status information to the user.
  63.  
  64. app.post('/login',
  65. passport.authenticate('local', { successRedirect: '/',
  66. failureRedirect: '/login',
  67. failureFlash: true })
  68. );
  69. Setting the failureFlash option to true instructs Passport to flash an error message using the message given by the strategy's verify callback, if any. This is often the best approach, because the verify callback can make the most accurate determination of why authentication failed.
  70.  
  71. Alternatively, the flash message can be set specifically.
  72.  
  73. passport.authenticate('local', { failureFlash: 'Invalid username or password.' });
  74. A successFlash option is available which flashes a success message when authentication succeeds.
  75.  
  76. passport.authenticate('local', { successFlash: 'Welcome!' });
  77. Note: Using flash messages requires a req.flash() function. Express 2.x provided this functionality, however it was removed from Express 3.x. Use of connect-flash middleware is recommended to provide this functionality when using Express 3.x.
  78.  
  79. Disable Sessions
  80.  
  81. After successful authentication, Passport will establish a persistent login session. This is useful for the common scenario of users accessing a web application via a browser. However, in some cases, session support is not necessary. For example, API servers typically require credentials to be supplied with each request. When this is the case, session support can be safely disabled by setting the session option to false.
  82.  
  83. app.get('/api/users/me',
  84. passport.authenticate('basic', { session: false }),
  85. function(req, res) {
  86. res.json({ id: req.user.id, username: req.user.username });
  87. });
  88. Custom Callback
  89.  
  90. If the built-in options are not sufficient for handling an authentication request, a custom callback can be provided to allow the application to handle success or failure.
  91.  
  92. app.get('/login', function(req, res, next) {
  93. passport.authenticate('local', function(err, user, info) {
  94. if (err) { return next(err); }
  95. if (!user) { return res.redirect('/login'); }
  96. req.logIn(user, function(err) {
  97. if (err) { return next(err); }
  98. return res.redirect('/users/' + user.username);
  99. });
  100. })(req, res, next);
  101. });
  102. In this example, note that authenticate() is called from within the route handler, rather than being used as route middleware. This gives the callback access to the req and res objects through closure.
  103.  
  104. If authentication failed, user will be set to false. If an exception occurred, err will be set. An optional info argument will be passed, containing additional details provided by the strategy's verify callback.
  105.  
  106. The callback can use the arguments supplied to handle the authentication result as desired. Note that when using a custom callback, it becomes the application's responsibility to establish a session (by calling req.login()) and send a response.
  107.  
  108. Configure
  109.  
  110. Three pieces need to be configured to use Passport for authentication:
  111.  
  112. Authentication strategies
  113. Application middleware
  114. Sessions (optional)
  115. Strategies
  116.  
  117. Passport uses what are termed strategies to authenticate requests. Strategies range from verifying a username and password, delegated authentication using OAuth or federated authentication using OpenID.
  118.  
  119. Before asking Passport to authenticate a request, the strategy (or strategies) used by an application must be configured.
  120.  
  121. Strategies, and their configuration, are supplied via the use() function. For example, the following uses the LocalStrategy for username/password authentication.
  122.  
  123. var passport = require('passport')
  124. , LocalStrategy = require('passport-local').Strategy;
  125.  
  126. passport.use(new LocalStrategy(
  127. function(username, password, done) {
  128. User.findOne({ username: username }, function (err, user) {
  129. if (err) { return done(err); }
  130. if (!user) {
  131. return done(null, false, { message: 'Incorrect username.' });
  132. }
  133. if (!user.validPassword(password)) {
  134. return done(null, false, { message: 'Incorrect password.' });
  135. }
  136. return done(null, user);
  137. });
  138. }
  139. ));
  140. Verify Callback
  141.  
  142. This example introduces an important concept. Strategies require what is known as a verify callback. The purpose of a verify callback is to find the user that possesses a set of credentials.
  143.  
  144. When Passport authenticates a request, it parses the credentials contained in the request. It then invokes the verify callback with those credentials as arguments, in this case username and password. If the credentials are valid, the verify callback invokes done to supply Passport with the user that authenticated.
  145.  
  146. return done(null, user);
  147. If the credentials are not valid (for example, if the password is incorrect), done should be invoked with false instead of a user to indicate an authentication failure.
  148.  
  149. return done(null, false);
  150. An additional info message can be supplied to indicate the reason for the failure. This is useful for displaying a flash message prompting the user to try again.
  151.  
  152. return done(null, false, { message: 'Incorrect password.' });
  153. Finally, if an exception occurred while verifying the credentials (for example, if the database is not available), done should be invoked with an error, in conventional Node style.
  154.  
  155. return done(err);
  156. Note that it is important to distinguish the two failure cases that can occur. The latter is a server exception, in which err is set to a non-null value. Authentication failures are natural conditions, in which the server is operating normally. Ensure that err remains null, and use the final argument to pass additional details.
  157.  
  158. By delegating in this manner, the verify callback keeps Passport database agnostic. Applications are free to choose how user information is stored, without any assumptions imposed by the authentication layer.
  159.  
  160. Middleware
  161.  
  162. In a Connect or Express-based application, passport.initialize() middleware is required to initialize Passport. If your application uses persistent login sessions, passport.session() middleware must also be used.
  163.  
  164. app.configure(function() {
  165. app.use(express.static('public'));
  166. app.use(express.cookieParser());
  167. app.use(express.bodyParser());
  168. app.use(express.session({ secret: 'keyboard cat' }));
  169. app.use(passport.initialize());
  170. app.use(passport.session());
  171. app.use(app.router);
  172. });
  173. Note that enabling session support is entirely optional, though it is recommended for most applications. If enabled, be sure to use express.session() before passport.session() to ensure that the login session is restored in the correct order.
  174.  
  175. Sessions
  176.  
  177. In a typical web application, the credentials used to authenticate a user will only be transmitted during the login request. If authentication succeeds, a session will be established and maintained via a cookie set in the user's browser.
  178.  
  179. Each subsequent request will not contain credentials, but rather the unique cookie that identifies the session. In order to support login sessions, Passport will serialize and deserialize user instances to and from the session.
  180.  
  181. passport.serializeUser(function(user, done) {
  182. done(null, user.id);
  183. });
  184.  
  185. passport.deserializeUser(function(id, done) {
  186. User.findById(id, function(err, user) {
  187. done(err, user);
  188. });
  189. });
  190. In this example, only the user ID is serialized to the session, keeping the amount of data stored within the session small. When subsequent requests are received, this ID is used to find the user, which will be restored to req.user.
  191.  
  192. The serialization and deserialization logic is supplied by the application, allowing the application to choose an appropriate database and/or object mapper, without imposition by the authentication layer.
  193.  
  194. Username & Password
  195.  
  196. The most widely used way for websites to authenticate users is via a username and password. Support for this mechanism is provided by the passport-local module.
  197.  
  198. Install
  199.  
  200. $ npm install passport-local
  201. Configuration
  202.  
  203. var passport = require('passport')
  204. , LocalStrategy = require('passport-local').Strategy;
  205.  
  206. passport.use(new LocalStrategy(
  207. function(username, password, done) {
  208. User.findOne({ username: username }, function(err, user) {
  209. if (err) { return done(err); }
  210. if (!user) {
  211. return done(null, false, { message: 'Incorrect username.' });
  212. }
  213. if (!user.validPassword(password)) {
  214. return done(null, false, { message: 'Incorrect password.' });
  215. }
  216. return done(null, user);
  217. });
  218. }
  219. ));
  220. The verify callback for local authentication accepts username and password arguments, which are submitted to the application via a login form.
  221.  
  222. Form
  223.  
  224. A form is placed on a web page, allowing the user to enter their credentials and log in.
  225.  
  226. <form action="/login" method="post">
  227. <div>
  228. <label>Username:</label>
  229. <input type="text" name="username"/>
  230. </div>
  231. <div>
  232. <label>Password:</label>
  233. <input type="password" name="password"/>
  234. </div>
  235. <div>
  236. <input type="submit" value="Log In"/>
  237. </div>
  238. </form>
  239. Route
  240.  
  241. The login form is submitted to the server via the POST method. Using authenticate() with the local strategy will handle the login request.
  242.  
  243. app.post('/login',
  244. passport.authenticate('local', { successRedirect: '/',
  245. failureRedirect: '/login',
  246. failureFlash: true })
  247. );
  248. Setting the failureFlash option to true instructs Passport to flash an error message using the message option set by the verify callback above. This is helpful when prompting the user to try again.
  249.  
  250. Parameters
  251.  
  252. By default, LocalStrategy expects to find credentials in parameters named username and password. If your site prefers to name these fields differently, options are available to change the defaults.
  253.  
  254. passport.use(new LocalStrategy({
  255. usernameField: 'email',
  256. passwordField: 'passwd'
  257. },
  258. function(username, password, done) {
  259. // ...
  260. }
  261. ));
  262. OpenID
  263.  
  264. OpenID is an open standard for federated authentication. When visiting a website, users present their OpenID to sign in. The user then authenticates with their chosen OpenID provider, which issues an assertion to confirm the user's identity. The website verifies this assertion in order to sign the user in.
  265.  
  266. Support for OpenID is provided by the passport-openid module.
  267.  
  268. Install
  269.  
  270. $ npm install passport-openid
  271. Configuration
  272.  
  273. When using OpenID, a return URL and realm must be specified. The returnURL is the URL to which the user will be redirected after authenticating with their OpenID provider. realm indicates the part of URL-space for which authentication is valid. Typically this will be the root URL of the website.
  274.  
  275. var passport = require('passport')
  276. , OpenIDStrategy = require('passport-openid').Strategy;
  277.  
  278. passport.use(new OpenIDStrategy({
  279. returnURL: 'http://www.example.com/auth/openid/return',
  280. realm: 'http://www.example.com/'
  281. },
  282. function(identifier, done) {
  283. User.findOrCreate({ openId: identifier }, function(err, user) {
  284. done(err, user);
  285. });
  286. }
  287. ));
  288. The verify callback for OpenID authentication accepts an identifier argument containing the user's claimed identifier.
  289.  
  290. Form
  291.  
  292. A form is placed on a web page, allowing the user to enter their OpenID and sign in.
  293.  
  294. <form action="/auth/openid" method="post">
  295. <div>
  296. <label>OpenID:</label>
  297. <input type="text" name="openid_identifier"/><br/>
  298. </div>
  299. <div>
  300. <input type="submit" value="Sign In"/>
  301. </div>
  302. </form>
  303. Routes
  304.  
  305. Two routes are required for OpenID authentication. The first route accepts the form submission containing an OpenID identifier. During authentication, the user will be redirected to their OpenID provider. The second route is the URL to which the user will be returned after authenticating with their OpenID provider.
  306.  
  307. // Accept the OpenID identifier and redirect the user to their OpenID
  308. // provider for authentication. When complete, the provider will redirect
  309. // the user back to the application at:
  310. // /auth/openid/return
  311. app.post('/auth/openid', passport.authenticate('openid'));
  312.  
  313. // The OpenID provider has redirected the user back to the application.
  314. // Finish the authentication process by verifying the assertion. If valid,
  315. // the user will be logged in. Otherwise, authentication has failed.
  316. app.get('/auth/openid/return',
  317. passport.authenticate('openid', { successRedirect: '/',
  318. failureRedirect: '/login' }));
  319. Profile Exchange
  320.  
  321. OpenID can optionally be configured to retrieve profile information about the user being authenticated. Profile exchange is enabled by setting the profile option to true.
  322.  
  323. passport.use(new OpenIDStrategy({
  324. returnURL: 'http://www.example.com/auth/openid/return',
  325. realm: 'http://www.example.com/',
  326. profile: true
  327. },
  328. function(identifier, profile, done) {
  329. // ...
  330. }
  331. ));
  332. When profile exchange is enabled, the function signature of the verify callback accepts an additional profile argument containing user profile information provided by the OpenID provider; refer to User Profile for further information.
  333.  
  334. OAuth
  335.  
  336. OAuth is a standard protocol that allows users to authorize API access to web and desktop or mobile applications. Once access has been granted, the authorized application can utilize the API on behalf of the user. OAuth has also emerged as a popular mechanism for delegated authentication.
  337.  
  338. OAuth comes in two primary flavors, both of which are widely deployed.
  339.  
  340. The initial version of OAuth was developed as an open standard by a loosely organized collective of web developers. Their work resulted in OAuth 1.0, which was superseded by OAuth 1.0a. This work has now been standardized by the IETF as RFC 5849.
  341.  
  342. Recent efforts undertaken by the Web Authorization Protocol Working Group have focused on defining OAuth 2.0. Due to the lengthy standardization effort, providers have proceeded to deploy implementations conforming to various drafts, each with slightly different semantics.
  343.  
  344. Thankfully, Passport shields an application from the complexities of dealing with OAuth variants. In many cases, a provider-specific strategy can be used instead of the generic OAuth strategies described below. This cuts down on the necessary configuration, and accommodates any provider-specific quirks. See Facebook, Twitter or the list of providers for preferred usage.
  345.  
  346. Support for OAuth is provided by the passport-oauth module.
  347.  
  348. Install
  349.  
  350. $ npm install passport-oauth
  351. OAuth 1.0
  352.  
  353. OAuth 1.0 is a delegated authentication strategy that involves multiple steps. First, a request token must be obtained. Next, the user is redirected to the service provider to authorize access. Finally, after authorization has been granted, the user is redirected back to the application and the request token can be exchanged for an access token. The application requesting access, known as a consumer, is identified by a consumer key and consumer secret.
  354.  
  355. Configuration
  356.  
  357. When using the generic OAuth strategy, the key, secret, and endpoints are specified as options.
  358.  
  359. var passport = require('passport')
  360. , OAuthStrategy = require('passport-oauth').OAuthStrategy;
  361.  
  362. passport.use('provider', new OAuthStrategy({
  363. requestTokenURL: 'https://www.provider.com/oauth/request_token',
  364. accessTokenURL: 'https://www.provider.com/oauth/access_token',
  365. userAuthorizationURL: 'https://www.provider.com/oauth/authorize',
  366. consumerKey: '123-456-789',
  367. consumerSecret: 'shhh-its-a-secret'
  368. callbackURL: 'https://www.example.com/auth/provider/callback'
  369. },
  370. function(token, tokenSecret, profile, done) {
  371. User.findOrCreate(..., function(err, user) {
  372. done(err, user);
  373. });
  374. }
  375. ));
  376. The verify callback for OAuth-based strategies accepts token, tokenSecret, and profile arguments. token is the access token and tokenSecret is its corresponding secret. profile will contain user profile information provided by the service provider; refer to User Profile for additional information.
  377.  
  378. Routes
  379.  
  380. Two routes are required for OAuth authentication. The first route initiates an OAuth transaction and redirects the user to the service provider. The second route is the URL to which the user will be redirected after authenticating with the provider.
  381.  
  382. // Redirect the user to the OAuth provider for authentication. When
  383. // complete, the provider will redirect the user back to the application at
  384. // /auth/provider/callback
  385. app.get('/auth/provider', passport.authenticate('provider'));
  386.  
  387. // The OAuth provider has redirected the user back to the application.
  388. // Finish the authentication process by attempting to obtain an access
  389. // token. If authorization was granted, the user will be logged in.
  390. // Otherwise, authentication has failed.
  391. app.get('/auth/provider/callback',
  392. passport.authenticate('provider', { successRedirect: '/',
  393. failureRedirect: '/login' }));
  394. Link
  395.  
  396. A link or button can be placed on a web page, which will start the authentication process when clicked.
  397.  
  398. <a href="/auth/provider">Log In with OAuth Provider</a>
  399. OAuth 2.0
  400.  
  401. OAuth 2.0 is the successor to OAuth 1.0, and is designed to overcome perceived shortcomings in the earlier version. The authentication flow is essentially the same. The user is first redirected to the service provider to authorize access. After authorization has been granted, the user is redirected back to the application with a code that can be exchanged for an access token. The application requesting access, known as a client, is identified by an ID and secret.
  402.  
  403. Configuration
  404.  
  405. When using the generic OAuth 2.0 strategy, the client ID, client secret, and endpoints are specified as options.
  406.  
  407. var passport = require('passport')
  408. , OAuth2Strategy = require('passport-oauth').OAuth2Strategy;
  409.  
  410. passport.use('provider', new OAuth2Strategy({
  411. authorizationURL: 'https://www.provider.com/oauth2/authorize',
  412. tokenURL: 'https://www.provider.com/oauth2/token',
  413. clientID: '123-456-789',
  414. clientSecret: 'shhh-its-a-secret'
  415. callbackURL: 'https://www.example.com/auth/provider/callback'
  416. },
  417. function(accessToken, refreshToken, profile, done) {
  418. User.findOrCreate(..., function(err, user) {
  419. done(err, user);
  420. });
  421. }
  422. ));
  423. The verify callback for OAuth 2.0-based strategies accepts accessToken, refreshToken, and profile arguments. refreshToken can be used to obtain new access tokens, and may be undefined if the provider does not issue refresh tokens. profile will contain user profile information provided by the service provider; refer to User Profile for additional information.
  424.  
  425. Routes
  426.  
  427. Two routes are required for OAuth 2.0 authentication. The first route redirects the user to the service provider. The second route is the URL to which the user will be redirected after authenticating with the provider.
  428.  
  429. // Redirect the user to the OAuth 2.0 provider for authentication. When
  430. // complete, the provider will redirect the user back to the application at
  431. // /auth/provider/callback
  432. app.get('/auth/provider', passport.authenticate('provider'));
  433.  
  434. // The OAuth 2.0 provider has redirected the user back to the application.
  435. // Finish the authentication process by attempting to obtain an access
  436. // token. If authorization was granted, the user will be logged in.
  437. // Otherwise, authentication has failed.
  438. app.get('/auth/provider/callback',
  439. passport.authenticate('provider', { successRedirect: '/',
  440. failureRedirect: '/login' }));
  441. Scope
  442.  
  443. When requesting access using OAuth 2.0, the scope of access is controlled by the scope option.
  444.  
  445. app.get('/auth/provider',
  446. passport.authenticate('provider', { scope: 'email' })
  447. );
  448. Multiple scopes can be specified as an array.
  449.  
  450. app.get('/auth/provider',
  451. passport.authenticate('provider', { scope: ['email', 'sms'] })
  452. );
  453. Values for the scope option are provider-specific. Consult the provider's documentation for details regarding supported scopes.
  454.  
  455. Link
  456.  
  457. A link or button can be placed on a web page, which will start the authentication process when clicked.
  458.  
  459. <a href="/auth/provider">Log In with OAuth 2.0 Provider</a>
  460. User Profile
  461.  
  462. When authenticating using a third-party service such as Facebook or Twitter, user profile information will often be available. Each service tends to have a different way of encoding this information. To make integration easier, Passport normalizes profile information to the extent possible.
  463.  
  464. Normalized profile information conforms to the contact schema established by Portable Contacts. The common fields available are outlined in the following table.
  465.  
  466. provider {String}
  467. The provider with which the user authenticated (facebook, twitter, etc.).
  468. id {String}
  469. A unique identifier for the user, as generated by the service provider.
  470. displayName {String}
  471. The name of this user, suitable for display.
  472. name {Object}
  473. familyName {String}
  474. The family name of this user, or "last name" in most Western languages.
  475. givenName {String}
  476. The given name of this user, or "first name" in most Western languages.
  477. middleName {String}
  478. The middle name of this user.
  479. emails {Array} [n]
  480. value {String}
  481. The actual email address.
  482. type {String}
  483. The type of email address (home, work, etc.).
  484. photos {Array} [n]
  485. value {String}
  486. The URL of the image.
  487. Note that not all of the above fields are available from every service provider. Some providers may contain additional information not described here. Consult the provider-specific documentation for further details.
  488.  
  489. Facebook
  490.  
  491. The Facebook strategy allows users to log in to a web application using their Facebook account. Internally, Facebook authentication works using OAuth 2.0.
  492.  
  493. Support for Facebook is implemented by the passport-facebook module.
  494.  
  495. Install
  496.  
  497. $ npm install passport-facebook
  498. Configuration
  499.  
  500. In order to use Facebook authentication, you must first create an app at Facebook Developers. When created, an app is assigned an App ID and App Secret. Your application must also implement a redirect URL, to which Facebook will redirect users after they have approved access for your application.
  501.  
  502. var passport = require('passport')
  503. , FacebookStrategy = require('passport-facebook').Strategy;
  504.  
  505. passport.use(new FacebookStrategy({
  506. clientID: FACEBOOK_APP_ID,
  507. clientSecret: FACEBOOK_APP_SECRET,
  508. callbackURL: "http://www.example.com/auth/facebook/callback"
  509. },
  510. function(accessToken, refreshToken, profile, done) {
  511. User.findOrCreate(..., function(err, user) {
  512. if (err) { return done(err); }
  513. done(null, user);
  514. });
  515. }
  516. ));
  517. The verify callback for Facebook authentication accepts accessToken, refreshToken, and profile arguments. profile will contain user profile information provided by Facebook; refer to User Profile for additional information.
  518.  
  519. Note: For security reasons, the redirection URL must reside on the same host that is registered with Facebook.
  520.  
  521. Routes
  522.  
  523. Two routes are required for Facebook authentication. The first route redirects the user to Facebook. The second route is the URL to which Facebook will redirect the user after they have logged in.
  524.  
  525. // Redirect the user to Facebook for authentication. When complete,
  526. // Facebook will redirect the user back to the application at
  527. // /auth/facebook/callback
  528. app.get('/auth/facebook', passport.authenticate('facebook'));
  529.  
  530. // Facebook will redirect the user to this URL after approval. Finish the
  531. // authentication process by attempting to obtain an access token. If
  532. // access was granted, the user will be logged in. Otherwise,
  533. // authentication has failed.
  534. app.get('/auth/facebook/callback',
  535. passport.authenticate('facebook', { successRedirect: '/',
  536. failureRedirect: '/login' }));
  537. Note that the URL of the callback route matches that of the callbackURL option specified when configuring the strategy.
  538.  
  539. Permissions
  540.  
  541. If your application needs extended permissions, they can be requested by setting the scope option.
  542.  
  543. app.get('/auth/facebook',
  544. passport.authenticate('facebook', { scope: 'read_stream' })
  545. );
  546. Multiple permissions can be specified as an array.
  547.  
  548. app.get('/auth/facebook',
  549. passport.authenticate('facebook', { scope: ['read_stream', 'publish_actions'] })
  550. );
  551. Link
  552.  
  553. A link or button can be placed on a web page, allowing one-click login with Facebook.
  554.  
  555. <a href="/auth/facebook">Login with Facebook</a>
  556. Twitter
  557.  
  558. The Twitter strategy allows users to sign in to a web application using their Twitter account. Internally, Twitter authentication works using OAuth 1.0a.
  559.  
  560. Support for Twitter is implemented by the passport-twitter module.
  561.  
  562. Install
  563.  
  564. $ npm install passport-twitter
  565. Configuration
  566.  
  567. In order to use Twitter authentication, you must first create an application at Twitter Developers. When created, an application is assigned a consumer key and consumer secret. Your application must also implement a callback URL, to which Twitter will redirect users after they have approved access for your application.
  568.  
  569. var passport = require('passport')
  570. , TwitterStrategy = require('passport-twitter').Strategy;
  571.  
  572. passport.use(new TwitterStrategy({
  573. consumerKey: TWITTER_CONSUMER_KEY,
  574. consumerSecret: TWITTER_CONSUMER_SECRET,
  575. callbackURL: "http://www.example.com/auth/twitter/callback"
  576. },
  577. function(token, tokenSecret, profile, done) {
  578. User.findOrCreate(..., function(err, user) {
  579. if (err) { return done(err); }
  580. done(null, user);
  581. });
  582. }
  583. ));
  584. The verify callback for Twitter authentication accepts token, tokenSecret, and profile arguments. profile will contain user profile information provided by Twitter; refer to User Profile for additional information.
  585.  
  586. Routes
  587.  
  588. Two routes are required for Twitter authentication. The first route initiates an OAuth transaction and redirects the user to Twitter. The second route is the URL to which Twitter will redirect the user after they have signed in.
  589.  
  590. // Redirect the user to Twitter for authentication. When complete, Twitter
  591. // will redirect the user back to the application at
  592. // /auth/twitter/callback
  593. app.get('/auth/twitter', passport.authenticate('twitter'));
  594.  
  595. // Twitter will redirect the user to this URL after approval. Finish the
  596. // authentication process by attempting to obtain an access token. If
  597. // access was granted, the user will be logged in. Otherwise,
  598. // authentication has failed.
  599. app.get('/auth/twitter/callback',
  600. passport.authenticate('twitter', { successRedirect: '/',
  601. failureRedirect: '/login' }));
  602. Note that the URL of the callback route matches that of the callbackURL option specified when configuring the strategy.
  603.  
  604. Link
  605.  
  606. A link or button can be placed on a web page, allowing one-click sign in with Twitter.
  607.  
  608. <a href="/auth/twitter">Sign in with Twitter</a>
  609. Google
  610.  
  611. The Google strategy allows users to sign in to a web application using their Google account. Google used to support OpenID internally, but it now works based on OpenID Connect and supports oAuth 1.0 and oAuth 2.0.
  612.  
  613. Support for Google is implemented by the passport-google-oauth module.
  614.  
  615. Install
  616.  
  617. $ npm install passport-google-oauth
  618. Configuration
  619.  
  620. The Client Id and Client Secret needed to authenticate with Google can be set up from the Google Developers Console. You may also need to enable Google+ API in the developer console, otherwise user profile data may not be fetched. Google supports authentication with both oAuth 1.0 and oAuth 2.0.
  621.  
  622. oAuth 1.0
  623.  
  624. The Google OAuth 1.0 authentication strategy authenticates users using a Google account and OAuth tokens. The strategy requires a verify callback, which accepts these credentials and calls done providing a user, as well as options specifying a consumer key, consumer secret, and callback URL.
  625.  
  626. Configuration
  627.  
  628. var passport = require('passport');
  629. var GoogleStrategy = require('passport-google-oauth').OAuthStrategy;
  630.  
  631. // Use the GoogleStrategy within Passport.
  632. // Strategies in passport require a `verify` function, which accept
  633. // credentials (in this case, a token, tokenSecret, and Google profile), and
  634. // invoke a callback with a user object.
  635. passport.use(new GoogleStrategy({
  636. consumerKey: GOOGLE_CONSUMER_KEY,
  637. consumerSecret: GOOGLE_CONSUMER_SECRET,
  638. callbackURL: "http://www.example.com/auth/google/callback"
  639. },
  640. function(token, tokenSecret, profile, done) {
  641. User.findOrCreate({ googleId: profile.id }, function (err, user) {
  642. return done(err, user);
  643. });
  644. }
  645. ));
  646. Routes
  647.  
  648. Use passport.authenticate(), specifying the 'google' strategy, to authenticate requests. Authentication with Google requires an extra scope parameter. For information, go here.
  649.  
  650. // GET /auth/google
  651. // Use passport.authenticate() as route middleware to authenticate the
  652. // request. The first step in Google authentication will involve redirecting
  653. // the user to google.com. After authorization, Google will redirect the user
  654. // back to this application at /auth/google/callback
  655. app.get('/auth/google',
  656. passport.authenticate('google', { scope: 'https://www.google.com/m8/feeds' });
  657.  
  658. // GET /auth/google/callback
  659. // Use passport.authenticate() as route middleware to authenticate the
  660. // request. If authentication fails, the user will be redirected back to the
  661. // login page. Otherwise, the primary route function function will be called,
  662. // which, in this example, will redirect the user to the home page.
  663. app.get('/auth/google/callback',
  664. passport.authenticate('google', { failureRedirect: '/login' }),
  665. function(req, res) {
  666. res.redirect('/');
  667. });
  668. oAuth 2.0
  669.  
  670. The Google OAuth 2.0 authentication strategy authenticates users using a Google account and OAuth 2.0 tokens. The strategy requires a verify callback, which accepts these credentials and calls done providing a user, as well as options specifying a client ID, client secret, and callback URL.
  671.  
  672. Configuration
  673.  
  674. var passport = require('passport');
  675. var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
  676.  
  677. // Use the GoogleStrategy within Passport.
  678. // Strategies in Passport require a `verify` function, which accept
  679. // credentials (in this case, an accessToken, refreshToken, and Google
  680. // profile), and invoke a callback with a user object.
  681. passport.use(new GoogleStrategy({
  682. clientID: GOOGLE_CLIENT_ID,
  683. clientSecret: GOOGLE_CLIENT_SECRET,
  684. callbackURL: "http://www.example.com/auth/google/callback"
  685. },
  686. function(accessToken, refreshToken, profile, done) {
  687. User.findOrCreate({ googleId: profile.id }, function (err, user) {
  688. return done(err, user);
  689. });
  690. }
  691. ));
  692. Routes
  693.  
  694. Use passport.authenticate(), specifying the 'google' strategy, to authenticate requests. Authentication with Google requires an extra scope parameter. For information, go here.
  695.  
  696. // GET /auth/google
  697. // Use passport.authenticate() as route middleware to authenticate the
  698. // request. The first step in Google authentication will involve
  699. // redirecting the user to google.com. After authorization, Google
  700. // will redirect the user back to this application at /auth/google/callback
  701. app.get('/auth/google',
  702. passport.authenticate('google', { scope: ['https://www.googleapis.com/auth/plus.login'] }));
  703.  
  704. // GET /auth/google/callback
  705. // Use passport.authenticate() as route middleware to authenticate the
  706. // request. If authentication fails, the user will be redirected back to the
  707. // login page. Otherwise, the primary route function function will be called,
  708. // which, in this example, will redirect the user to the home page.
  709. app.get('/auth/google/callback',
  710. passport.authenticate('google', { failureRedirect: '/login' }),
  711. function(req, res) {
  712. res.redirect('/');
  713. });
  714. Link
  715.  
  716. A link or button can be placed on a web page, allowing one-click sign in with Google.
  717.  
  718. <a href="/auth/google">Sign In with Google</a>
  719. Basic & Digest
  720.  
  721. Along with defining HTTP's authentication framework, RFC 2617 also defined the Basic and Digest authentications schemes. These two schemes both use usernames and passwords as credentials to authenticate users, and are often used to protect API endpoints.
  722.  
  723. It should be noted that relying on username and password creditials can have adverse security impacts, especially in scenarios where there is not a high degree of trust between the server and client. In these situations, it is recommended to use an authorization framework such as OAuth 2.0.
  724.  
  725. Support for Basic and Digest schemes is provided by the passport-http module.
  726.  
  727. Install
  728.  
  729. $ npm install passport-http
  730. Basic
  731.  
  732. The Basic scheme uses a username and password to authenticate a user. These credentials are transported in plain text, so it is advised to use HTTPS when implementing this scheme.
  733.  
  734. Configuration
  735.  
  736. passport.use(new BasicStrategy(
  737. function(username, password, done) {
  738. User.findOne({ username: username }, function (err, user) {
  739. if (err) { return done(err); }
  740. if (!user) { return done(null, false); }
  741. if (!user.validPassword(password)) { return done(null, false); }
  742. return done(null, user);
  743. });
  744. }
  745. ));
  746. The verify callback for Basic authentication accepts username and password arguments.
  747.  
  748. Protect Endpoints
  749.  
  750. app.get('/api/me',
  751. passport.authenticate('basic', { session: false }),
  752. function(req, res) {
  753. res.json(req.user);
  754. });
  755. Specify passport.authenticate() with the basic strategy to protect API endpoints. Sessions are not typically needed by APIs, so they can be disabled.
  756.  
  757. Digest
  758.  
  759. The Digest scheme uses a username and password to authenticate a user. Its primary benefit over Basic is that it uses a challenge-response paradigm to avoid sending the password in the clear.
  760.  
  761. Configuration
  762.  
  763. passport.use(new DigestStrategy({ qop: 'auth' },
  764. function(username, done) {
  765. User.findOne({ username: username }, function (err, user) {
  766. if (err) { return done(err); }
  767. if (!user) { return done(null, false); }
  768. return done(null, user, user.password);
  769. });
  770. },
  771. function(params, done) {
  772. // validate nonces as necessary
  773. done(null, true)
  774. }
  775. ));
  776. The Digest strategy utilizes two callbacks, the second of which is optional.
  777.  
  778. The first callback, known as the "secret callback" accepts the username and calls done supplying a user and the corresponding secret password. The password is used to compute a hash, and authentication fails if it does not match that contained in the request.
  779.  
  780. The second "validate callback" accepts nonce related params, which can be checked to avoid replay attacks.
  781.  
  782. Protect Endpoints
  783.  
  784. app.get('/api/me',
  785. passport.authenticate('digest', { session: false }),
  786. function(req, res) {
  787. res.json(req.user);
  788. });
  789. Specify passport.authenticate() with the digest strategy to protect API endpoints. Sessions are not typically needed by APIs, so they can be disabled.
  790.  
  791. OAuth
  792.  
  793. OAuth (formally specified by RFC 5849) provides a means for users to grant third-party applications access to their data without exposing their password to those applications.
  794.  
  795. The protocol greatly improves the security of web applications, in particular, and OAuth has been important in bringing attention to the potential dangers of exposing passwords to external services.
  796.  
  797. While OAuth 1.0 is still widely used, it has been superseded by OAuth 2.0. It is recommended to base new implementations on OAuth 2.0.
  798.  
  799. When using OAuth to protect API endpoints, there are three distinct steps that that must be performed:
  800.  
  801. The application requests permission from the user for access to protected resources.
  802. A token is issued to the application, if permission is granted by the user.
  803. The application authenticates using the token to access protected resources.
  804. Issuing Tokens
  805.  
  806. OAuthorize, a sibling project to Passport, provides a toolkit for implementing OAuth service providers.
  807.  
  808. The authorization process is a complex sequence that involves authenticating both the requesting application and the user, as well as prompting the user for permission, ensuring that enough detail is provided for the user to make an informed decision.
  809.  
  810. Additionally, it is up to the implementor to determine what limits can be placed on the application regarding scope of access, as well as subsequently enforcing those limits.
  811.  
  812. As a toolkit, OAuthorize does not attempt to make implementation decisions. This guide does not cover these issues, but does highly recommend that services deploying OAuth have a complete understanding of the security considerations involved.
  813.  
  814. Authenticating Tokens
  815.  
  816. Once issued, OAuth tokens can be authenticated using the passport-http-oauth module.
  817.  
  818. Install
  819.  
  820. $ npm install passport-http-oauth
  821. Configuration
  822.  
  823. passport.use('token', new TokenStrategy(
  824. function(consumerKey, done) {
  825. Consumer.findOne({ key: consumerKey }, function (err, consumer) {
  826. if (err) { return done(err); }
  827. if (!consumer) { return done(null, false); }
  828. return done(null, consumer, consumer.secret);
  829. });
  830. },
  831. function(accessToken, done) {
  832. AccessToken.findOne({ token: accessToken }, function (err, token) {
  833. if (err) { return done(err); }
  834. if (!token) { return done(null, false); }
  835. Users.findById(token.userId, function(err, user) {
  836. if (err) { return done(err); }
  837. if (!user) { return done(null, false); }
  838. // fourth argument is optional info. typically used to pass
  839. // details needed to authorize the request (ex: `scope`)
  840. return done(null, user, token.secret, { scope: token.scope });
  841. });
  842. });
  843. },
  844. function(timestamp, nonce, done) {
  845. // validate the timestamp and nonce as necessary
  846. done(null, true)
  847. }
  848. ));
  849. In contrast to other strategies, there are two callbacks required by OAuth. In OAuth, both an identifier for the requesting application and the user-specific token are encoded as credentials.
  850.  
  851. The first callback is known as the "consumer callback", and is used to find the application making the request, including the secret assigned to it. The second callback is the "token callback", which is used to indentify the user as well as the token's corresponding secret. The secrets supplied by the consumer and token callbacks are used to compute a signature, and authentication fails if it does not match the request signature.
  852.  
  853. A final "validate callback" is optional, which can be used to prevent replay attacks by checking the timestamp and nonce used in the request.
  854.  
  855. Protect Endpoints
  856.  
  857. app.get('/api/me',
  858. passport.authenticate('token', { session: false }),
  859. function(req, res) {
  860. res.json(req.user);
  861. });
  862. Specify passport.authenticate() with the token strategy to protect API endpoints. Sessions are not typically needed by APIs, so they can be disabled.
  863.  
  864. OAuth 2.0
  865.  
  866. OAuth 2.0 (formally specified by RFC 6749) provides an authorization framework which allows users to authorize access to third-party applications. When authorized, the application is issued a token to use as an authentication credential. This has two primary security benefits:
  867.  
  868. The application does not need to store the user's username and password.
  869. The token can have a restricted scope (for example: read-only access).
  870. These benefits are particularly important for ensuring the security of web applications, making OAuth 2.0 the predominant standard for API authentication.
  871.  
  872. When using OAuth 2.0 to protect API endpoints, there are three distinct steps that must be performed:
  873.  
  874. The application requests permission from the user for access to protected resources.
  875. A token is issued to the application, if permission is granted by the user.
  876. The application authenticates using the token to access protected resources.
  877. Issuing Tokens
  878.  
  879. OAuth2orize, a sibling project to Passport, provides a toolkit for implementing OAuth 2.0 authorization servers.
  880.  
  881. The authorization process is a complex sequence that involves authenticating both the requesting application and the user, as well as prompting the user for permission, ensuring that enough detail is provided for the user to make an informed decision.
  882.  
  883. Additionally, it is up to the implementor to determine what limits can be placed on the application regarding scope of access, as well as subsequently enforcing those limits.
  884.  
  885. As a toolkit, OAuth2orize does not attempt to make implementation decisions. This guide does not cover these issues, but does highly recommend that services deploying OAuth 2.0 have a complete understanding of the security considerations involved.
  886.  
  887. Authenticating Tokens
  888.  
  889. OAuth 2.0 provides a framework, in which an arbitrarily extensible set of token types can be issued. In practice, only specific token types have gained widespread use.
  890.  
  891. Bearer Tokens
  892.  
  893. Bearer tokens are the most widely issued type of token in OAuth 2.0. So much so, in fact, that many implementations assume that bearer tokens are the only type of token issued.
  894.  
  895. Bearer tokens can be authenticated using the passport-http-bearer module.
  896.  
  897. Install
  898.  
  899. $ npm install passport-http-bearer
  900. Configuration
  901.  
  902. passport.use(new BearerStrategy(
  903. function(token, done) {
  904. User.findOne({ token: token }, function (err, user) {
  905. if (err) { return done(err); }
  906. if (!user) { return done(null, false); }
  907. return done(null, user, { scope: 'read' });
  908. });
  909. }
  910. ));
  911. The verify callback for bearer tokens accepts the token as an argument. When invoking done, optional info can be passed, which will be set by Passport at req.authInfo. This is typically used to convey the scope of the token, and can be used when making access control checks.
  912.  
  913. Protect Endpoints
  914.  
  915. app.get('/api/me',
  916. passport.authenticate('bearer', { session: false }),
  917. function(req, res) {
  918. res.json(req.user);
  919. });
  920. Specify passport.authenticate() with the bearer strategy to protect API endpoints. Sessions are not typically needed by APIs, so they can be disabled.
  921.  
  922. API Schemes
  923.  
  924. The following is a list of strategies that implement authentication schemes used when protecting API endpoints.
  925.  
  926. Scheme Specification Developer
  927. Anonymous N/A Jared Hanson
  928. Bearer RFC 6750 Jared Hanson
  929. Basic RFC 2617 Jared Hanson
  930. Digest RFC 2617 Jared Hanson
  931. Hash N/A Yuri Karadzhov
  932. Hawk hueniverse/hawk José F. Romaniello
  933. Local API Key N/A Sudhakar Mani
  934. OAuth RFC 5849 Jared Hanson
  935. OAuth 2.0 Client Password RFC 6749 Jared Hanson
  936. OAuth 2.0 JWT Client Assertion draft-jones-oauth-jwt-bearer xTuple
  937. OAuth 2.0 Public Client RFC 6749 Tim Shadel
  938. Log In
  939.  
  940. Passport exposes a login() function on req (also aliased as logIn()) that can be used to establish a login session.
  941.  
  942. req.login(user, function(err) {
  943. if (err) { return next(err); }
  944. return res.redirect('/users/' + req.user.username);
  945. });
  946. When the login operation completes, user will be assigned to req.user.
  947.  
  948. Note: passport.authenticate() middleware invokes req.login() automatically. This function is primarily used when users sign up, during which req.login() can be invoked to automatically log in the newly registered user.
  949.  
  950. Log Out
  951.  
  952. Passport exposes a logout() function on req (also aliased as logOut()) that can be called from any route handler which needs to terminate a login session. Invoking logout() will remove the req.user property and clear the login session (if any).
  953.  
  954. app.get('/logout', function(req, res){
  955. req.logout();
  956. res.redirect('/');
  957. });
  958. Authorize
  959.  
  960. An application may need to incorporate information from multiple third-party services. In this case, the application will request the user to "connect", for example, both their Facebook and Twitter accounts.
  961.  
  962. When this occurs, a user will already be authenticated with the application, and any subsequent third-party accounts merely need to be authorized and associated with the user. Because authentication and authorization in this situation are similar, Passport provides a means to accommodate both.
  963.  
  964. Authorization is performed by calling passport.authorize(). If authorization is granted, the result provided by the strategy's verify callback will be assigned to req.account. The existing login session and req.user will be unaffected.
  965.  
  966. app.get('/connect/twitter',
  967. passport.authorize('twitter-authz', { failureRedirect: '/account' })
  968. );
  969.  
  970. app.get('/connect/twitter/callback',
  971. passport.authorize('twitter-authz', { failureRedirect: '/account' }),
  972. function(req, res) {
  973. var user = req.user;
  974. var account = req.account;
  975.  
  976. // Associate the Twitter account with the logged-in user.
  977. account.userId = user.id;
  978. account.save(function(err) {
  979. if (err) { return self.error(err); }
  980. self.redirect('/');
  981. });
  982. }
  983. );
  984. In the callback route, you can see the use of both req.user and req.account. The newly connected account is associated with the logged-in user and saved to the database.
  985.  
  986. Configuration
  987.  
  988. Strategies used for authorization are the same as those used for authentication. However, an application may want to offer both authentication and authorization with the same third-party service. In this case, a named strategy can be used, by overriding the strategy's default name in the call to use().
  989.  
  990. passport.use('twitter-authz', new TwitterStrategy({
  991. consumerKey: TWITTER_CONSUMER_KEY,
  992. consumerSecret: TWITTER_CONSUMER_SECRET,
  993. callbackURL: "http://www.example.com/connect/twitter/callback"
  994. },
  995. function(token, tokenSecret, profile, done) {
  996. Account.findOne({ domain: 'twitter.com', uid: profile.id }, function(err, account) {
  997. if (err) { return done(err); }
  998. if (account) { return done(null, account); }
  999.  
  1000. var account = new Account();
  1001. account.domain = 'twitter.com';
  1002. account.uid = profile.id;
  1003. var t = { kind: 'oauth', token: token, attributes: { tokenSecret: tokenSecret } };
  1004. account.tokens.push(t);
  1005. return done(null, account);
  1006. });
  1007. }
  1008. ));
  1009. In the above example, you can see that the twitter-authz strategy is finding or creating an Account instance to store Twitter account information. The result will be assigned to req.account, allowing the route handler to associate the account with the authenticated user.
  1010.  
  1011. Association in Verify Callback
  1012.  
  1013. One downside to the approach described above is that it requires two instances of the same strategy and supporting routes.
  1014.  
  1015. To avoid this, set the strategy's passReqToCallback option to true. With this option enabled, req will be passed as the first argument to the verify callback.
  1016.  
  1017. passport.use(new TwitterStrategy({
  1018. consumerKey: TWITTER_CONSUMER_KEY,
  1019. consumerSecret: TWITTER_CONSUMER_SECRET,
  1020. callbackURL: "http://www.example.com/auth/twitter/callback",
  1021. passReqToCallback: true
  1022. },
  1023. function(req, token, tokenSecret, profile, done) {
  1024. if (!req.user) {
  1025. // Not logged-in. Authenticate based on Twitter account.
  1026. } else {
  1027. // Logged in. Associate Twitter account with user. Preserve the login
  1028. // state by supplying the existing user after association.
  1029. // return done(null, req.user);
  1030. }
  1031. }
  1032. ));
  1033. With req passed as an argument, the verify callback can use the state of the request to tailor the authentication process, handling both authentication and authorization using a single strategy instance and set of routes. For example, if a user is already logged in, the newly "connected" account can be associated. Any additional application-specific properties set on req, including req.session, can be used as well.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement