Skip to content

Commit

Permalink
feat(example-passport-login): add Twitter impl
Browse files Browse the repository at this point in the history
Signed-off-by: Diana Lau <dhmlau@ca.ibm.com>
  • Loading branch information
dhmlau committed Sep 17, 2020
1 parent 4e5a128 commit dbe382d
Show file tree
Hide file tree
Showing 20 changed files with 338 additions and 47 deletions.
8 changes: 0 additions & 8 deletions examples/passport-login/.eslintrc.js

This file was deleted.

3 changes: 3 additions & 0 deletions examples/passport-login/.gitignore
Expand Up @@ -65,3 +65,6 @@ typings/

# Cache used by TypeScript's incremental build
*.tsbuildinfo

# OAuth2 provider values
oauth2-providers.json
83 changes: 74 additions & 9 deletions examples/passport-login/README.md
Expand Up @@ -32,7 +32,7 @@ party apps

- [Facebook](https://developers.facebook.com/apps)
- [Google](https://console.developers.google.com/project)
- [twitter](https://apps.twitter.com/) **Not yet implemented**
- [twitter](https://developer.twitter.com/apps)

## Authentication using passport strategies as Express middleware

Expand Down Expand Up @@ -69,11 +69,11 @@ Start the application with
$ npm start
```

To use Google or Facebook logins, you'll need:
To use Google, Facebook or Twitter logins, you'll need:

- Copy `oauth2-providers.template.json` from this example project's root to
`oauth2-providers.json`.
- Update Google/Facebook configuration in the json file.
- Update Google/Facebook/Twitter configuration in the json file.
- Set `OAUTH_PROVIDERS_LOCATION` environment variable to
`../oauth2-providers.json`.

Expand All @@ -93,9 +93,9 @@ Open browser to http://localhost:3000

1. Click on `Login` from the header menu, You will see various buttons under
`Other login options`.
- [Facebook](#Try-it-out-with-FaceBook)
- [Facebook](#Try-it-out-with-Facebook)
- [Google](#Try-it-out-with-Google)
- `Twitter` - not yet implemented
- [Twitter](#Try-it-out-with-Twitter)
2. When you click on any login option, the page is redirected to that social
app's login page. On successful login with the social app, the `View account`
page is loaded.
Expand All @@ -108,9 +108,9 @@ Open browser to http://localhost:3000

1. Click on `Login` from the header menu, You will see various buttons under
`Other login options`.
- [Facebook](#Try-it-out-with-FaceBook)
- [Facebook](#Try-it-out-with-Facebook)
- [Google](#Try-it-out-with-Google)
- `Twitter` - not yet implemented
- [Twitter](#Try-it-out-with-Twitter)
2. When you click on any login option, the page is redirected to that social
app's login page. On successful login with the social app, the `View account`
page is loaded.
Expand All @@ -120,9 +120,9 @@ Open browser to http://localhost:3000
`linked accounts` section.
4. Click on Logout to log out of user session

## Try it out with FaceBook
## Try it out with Facebook

### Create a test app and test user in FaceBook
### Create a test app and test user in Facebook

1. Login to Facebook developer console: https://developers.facebook.com/apps
2. Click on `My Apps` tab in the dashboard menu, and then select `Add a new App`
Expand Down Expand Up @@ -230,3 +230,68 @@ http://loopback.io/doc/en/lb2/Configuring-providers.json.html.
- Click on `Log In with Google` button
- Google login page opens, enter Google user-id and password
- example app loads again on successful login

## Try it out with Twitter

### Create a test app and test user in Twitter

1. Login to Twitter developer page: https://developer.twitter.com/apps
2. Click on `Create an app` to create a new app.
3. In the `App details` page, fill the `callback URL` field with
`http://localhost:3000/api/auth/thirdparty/twitter/callback`.
4. In the same page, you also need to fill in the `Terms of Service URL` and
`Privacy policy URL`. This is needed since we will need to request users for
email address in the `Permissions` settings.
5. In the `Keys and tokens` tab, no changes are needed. You will see the
`Consumer API keys` section which has the API key and secret. These values
will be used in the LoopBack application.
6. In the `Permissions` tab, under `additional permissions` section, select
`Request email address`. Make sure you have the term of service and privacy
policy urls information filled in in the `Add details` tab, otherwise the
`Request email address` will be disabled for you.

- NOTE:
- If you change the permission settings after the app is being created, you
might need to regenerate the tokens again by going to the `Keys and tokens`
tab for regeneration.
- For details in getting email address from the login profile, see
[this discussion in `passport-twitter` repo](https://github.com/jaredhanson/passport-twitter/issues/67).
- The
[passport-twitter strategy](http://www.passportjs.org/packages/passport-twitter/)
used in this example is using OAuth 1.0a API.

### Create oauth2-providers.json

- Copy `oauth2-providers.template.json` from this example project's root to
`oauth2-providers.json`
- Update Twitter oauth config with the values for `consumerKey/consumerSecret`
from your test app.

```json
"twitter-login": {
"provider": "twitter",
"module": "passport-twitter",
"strategy": "OAuth2Strategy",
"consumerKey": "xxxxxxxxxxxxxx",
"consumerSecret": "xxxxxxxxxxxxxxx",
"callbackURL": "/api/auth/thirdparty/twitter/callback?source=twitter",
"authPath": "/api/auth/thirdparty/twitter",
"callbackPath": "/api/auth/thirdparty/twitter/callback",
"successRedirect": "/auth/account",
"failureRedirect": "/login",
"includeEmail": true,
"scope": ["email", "profile"],
"failureFlash": true
},
```

### Log in with Twitter

- Open your browser to the example app with `http://localhost:3000`
- Click `Log In` from the example app header menu
- Click on `Log In with Twitter` button
- You'll be asked to authorize the Twitter app to access your account. Click
`Authorize app`.
- Example app loads again on successful login
- Redirect to example app will fail if Twitter did not return profile with
email-id
15 changes: 15 additions & 0 deletions examples/passport-login/data/oauth2-test-provider.json
Expand Up @@ -31,6 +31,21 @@
"scope": ["email", "profile"],
"failureFlash": true
},
"twitter-login": {
"provider": "twitter",
"module": "passport-twitter",
"strategy": "OAuth2Strategy",
"consumerKey": "{twitter-consumer-key}",
"consumerSecret": "{twitter-consumer-secret}",
"callbackURL": "/api/auth/thirdparty/twitter/callback?source=twitter",
"authPath": "/api/auth/thirdparty/twitter",
"callbackPath": "/api/auth/thirdparty/twitter/callback",
"successRedirect": "/auth/account",
"failureRedirect": "/login",
"includeEmail": true,
"scope": ["email", "profile"],
"failureFlash": true
},
"oauth2": {
"provider": "oauth2",
"module": "passport-oauth2",
Expand Down
15 changes: 15 additions & 0 deletions examples/passport-login/oauth2-providers.template.json
Expand Up @@ -28,6 +28,21 @@
"scope": ["email", "profile"],
"failureFlash": true
},
"twitter-login": {
"provider": "twitter",
"module": "passport-twitter",
"strategy": "OAuth2Strategy",
"consumerKey": "{twitter-consumer-key}",
"consumerSecret": "{twitter-consumer-secret}",
"callbackURL": "/api/auth/thirdparty/twitter/callback?source=twitter",
"authPath": "/api/auth/thirdparty/twitter",
"callbackPath": "/api/auth/thirdparty/twitter/callback",
"successRedirect": "/auth/account",
"failureRedirect": "/login",
"includeEmail": true,
"scope": ["email", "profile"],
"failureFlash": true
},
"oauth2": {
"provider": "oauth2",
"module": "passport-oauth2",
Expand Down
41 changes: 41 additions & 0 deletions examples/passport-login/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions examples/passport-login/package.json
Expand Up @@ -54,6 +54,7 @@
"@types/passport-facebook": "^2.1.10",
"@types/passport-google-oauth": "^1.0.41",
"@types/passport-google-oauth2": "^0.1.3",
"@types/passport-twitter": "1.0.34",
"@types/passport-http": "^0.3.8",
"@types/passport-local": "^1.0.33",
"@types/passport-oauth2": "^1.4.9",
Expand All @@ -68,6 +69,7 @@
"passport-facebook": "^3.0.0",
"passport-google": "^0.3.0",
"passport-google-oauth2": "^0.2.0",
"passport-twitter": "1.0.4",
"passport-http": "^0.3.0",
"passport-local": "^1.0.0",
"passport-oauth2": "^1.5.0",
Expand Down
52 changes: 32 additions & 20 deletions examples/passport-login/src/application.ts
Expand Up @@ -3,38 +3,42 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

import {AuthenticationComponent} from '@loopback/authentication';
import {BootMixin} from '@loopback/boot';
import {ApplicationConfig, createBindingFromClass} from '@loopback/core';
import {RepositoryMixin} from '@loopback/repository';
import {RestApplication, toInterceptor} from '@loopback/rest';
import {CrudRestComponent} from '@loopback/rest-crud';
import {ServiceMixin} from '@loopback/service-proxy';
import {MySequence} from './sequence';
import {AuthenticationComponent} from '@loopback/authentication';
import passport from 'passport';
import {
FaceBookOauth2Authorization,
GoogleOauth2Authorization,
Oauth2AuthStrategy,
CustomOauth2Interceptor,
FacebookOauthInterceptor,
GoogleOauthInterceptor,
SessionAuth,
TwitterOauthInterceptor,
} from './authentication-interceptors';
import {
BasicStrategy,
FaceBookOauth2Authentication,
GoogleOauth2Authentication,
LocalAuthStrategy,
Oauth2AuthStrategy,
SessionStrategy,
BasicStrategy,
TwitterOauthAuthentication,
} from './authentication-strategies';
import {
FacebookOauth,
GoogleOauth,
CustomOauth2,
CustomOauth2ExpressMiddleware,
FacebookOauth,
FacebookOauth2ExpressMiddleware,
GoogleOauth,
GoogleOauth2ExpressMiddleware,
CustomOauth2ExpressMiddleware,
TwitterOauth,
TwitterOauthExpressMiddleware,
} from './authentication-strategy-providers';
import {
SessionAuth,
FacebookOauthInterceptor,
GoogleOauthInterceptor,
CustomOauth2Interceptor,
} from './authentication-interceptors';
import {MySequence} from './sequence';
import {PassportUserIdentityService, UserServiceBindings} from './services';
import {ApplicationConfig, createBindingFromClass} from '@loopback/core';
import {CrudRestComponent} from '@loopback/rest-crud';
import passport from 'passport';

export class OAuth2LoginApplication extends BootMixin(
ServiceMixin(RepositoryMixin(RestApplication)),
Expand Down Expand Up @@ -79,6 +83,7 @@ export class OAuth2LoginApplication extends BootMixin(
this.add(createBindingFromClass(FacebookOauth, {key: 'facebookStrategy'}));
this.add(createBindingFromClass(GoogleOauth, {key: 'googleStrategy'}));
this.add(createBindingFromClass(CustomOauth2, {key: 'oauth2Strategy'}));
this.add(createBindingFromClass(TwitterOauth, {key: 'twitterStrategy'}));
// passport express middleware
this.add(
createBindingFromClass(FacebookOauth2ExpressMiddleware, {
Expand All @@ -90,15 +95,21 @@ export class OAuth2LoginApplication extends BootMixin(
key: 'googleStrategyMiddleware',
}),
);
this.add(
createBindingFromClass(TwitterOauthExpressMiddleware, {
key: 'twitterStrategyMiddleware',
}),
);
this.add(
createBindingFromClass(CustomOauth2ExpressMiddleware, {
key: 'oauth2StrategyMiddleware',
}),
);
// LoopBack 4 style authentication strategies
this.add(createBindingFromClass(LocalAuthStrategy));
this.add(createBindingFromClass(FaceBookOauth2Authorization));
this.add(createBindingFromClass(GoogleOauth2Authorization));
this.add(createBindingFromClass(FaceBookOauth2Authentication));
this.add(createBindingFromClass(GoogleOauth2Authentication));
this.add(createBindingFromClass(TwitterOauthAuthentication));
this.add(createBindingFromClass(Oauth2AuthStrategy));
this.add(createBindingFromClass(SessionStrategy));
this.add(createBindingFromClass(BasicStrategy));
Expand All @@ -107,6 +118,7 @@ export class OAuth2LoginApplication extends BootMixin(
this.bind('passport-session-mw').to(toInterceptor(passport.session()));
this.bind('passport-facebook').toProvider(FacebookOauthInterceptor);
this.bind('passport-google').toProvider(GoogleOauthInterceptor);
this.bind('passport-twitter').toProvider(TwitterOauthInterceptor);
this.bind('passport-oauth2').toProvider(CustomOauth2Interceptor);
this.bind('set-session-user').toProvider(SessionAuth);
}
Expand Down
Expand Up @@ -3,8 +3,9 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

export * from './types';
export * from './oauth2.interceptor';
export * from './session.interceptor';
export * from './facebook.interceptor';
export * from './google.interceptor';
export * from './oauth2.interceptor';
export * from './session.interceptor';
export * from './twitter.interceptor';
export * from './types';

0 comments on commit dbe382d

Please sign in to comment.