-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.js
158 lines (151 loc) · 5.65 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/**
* PingOne Integration with a Traditional Web App
*
* This is part of the walkthrough guide (see
* https://github.com/dbrowski/pingone-express_js-sample-app-guide#readme).
*
* This is a "traditional web app" (a web app with a server component as opposed
* to a SPA or client-side app) is used to demonstrate how to add authentication
* using PingOne.
*
* Express is a Node.js web app framework that is used here to create the web
* app, but the steps can be used on most Node.js apps. And, understanding the
* steps from this guide can even help you integrate PingOne with
* SPA/client-side apps and other traditional web apps not using Node.js.
*/
/**
* Express Server Config and Initialization
*/
const express = require("express");
const app = express();
const port = 3000;
// Allows us to read values from ".env" file.
require("dotenv").config();
/**
* To start, create a copy of the '.env.EXAMPLE' file, and name the file '.env'.
* Then, fill in the required PingOne values using the config values from an
* (oidc web app) app connection.
*
* On the app connection, don't forget to set the redirect_uri to be http://
* localhost:3000/callback on the configuration tab of the app connection in the
* admin console.
*
* Finally, don't forget to click the toggle in the top right to turn it on!
*/
// PingOne Auth (authentication/authorization) base url
const authBaseURL = process.env.PINGONE_AUTH_BASE_URL;
// PingOne Environment ID (the ID of environment where the App Connection is
// located)
const envID = process.env.PINGONE_ENVIRONMENT_ID;
// PingOne Client ID of the App Connection
const clientID = process.env.PINGONE_CLIENT_ID;
// PingOne Client Secret of the App Connection
const clientSecret = process.env.PINGONE_CLIENT_SECRET;
// Express app (this app) base url (e.g., http://localhost)
const appBaseURL = process.env.APP_BASE_URL;
/**
* Some constants we'll need for an OAuth Authorization Code flow.
* We'll also add Authentication with OIDC.
*/
// This app's base origin (e.g., http://localhost:3000)
const appBaseOrigin = appBaseURL + ":" + port;
// PingOne authorize endpoint
const authorizeEndpoint = "/as/authorize";
// PingOne token endpoint
const tokenEndpoint = "/as/token";
// The url path made available for when the user is redirected back from the
// authorization server, PingOne
const callbackPath = "/callback";
// The full url where the user is redirected after authenticating/authorizing
// with PingOne (e.g., http://localhost:3000/callback)
const redirectURI = appBaseOrigin + callbackPath;
/**
* Scopes specify what kind of access the client is requesting from the user.
*
* For example, "openid" is a scope which requests access to some basic user
* info. It's also the default resource on a PingOne OAuth/OIDC app connection
*
*
* Scopes not added to the app connection (you can see and modify them on the
* Resources tab) will be ignored by the authorization server even if requested
* by the client. Otherwise, additional scopes can be appended after a space.
*
*
* Some other examples of scopes you can add:
*
* profile - access to basic user info;
*
* p1:read:user - access to read the authenticating user's info attributes (a
* PingOne-specific scope for reading the user's associated PingOne Identity)
*/
const scopes = "openid";
// The OAuth 2.0 grant type and associated type of response expected from the
// /authorize endpoint. The Authorization Code flow is recommended as the best
// practice in most cases
// https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-23
const grantType = "authorization_code";
const responseType = "code";
/**
* Root path - "http://localhost:3000"
*
* Navigating to the root path should render "Hello Step1!" along with some text
* containing the environment and client id's from your .env file.
*
* *If instead of an id you see "undefined" or nothing, make sure you've created
* *the .env file (at the root of the repo) and populated it with the id's.
*/
app.get("/", (req, res) => {
res.send(
"Hello Step1!" +
"<br /> <br />" +
"<strong> If you're seeing \"undefined\", make sure that you've correctly created the .env file as instructed in the </strong>" +
'<a href="https://github.com/dbrowski/pingone-express_js-sample-app-guide#creating-the-environment-file" target="_blank">README</a>.' +
"<br /> <br />" +
`Environment ID: ${envID}` +
"<br />" +
`Client ID: ${clientID}`
);
});
/**
* This outputs a message (modified to show you the current step) to your
* terminal (where you started the app) when the Express server starts up.
*/
app.listen(port, () => {
console.log(
`The PingOne sample Express app has started listening on ${appBaseURL}:${port}`
);
console.log("Step 1 - Reading environment variables from .env.");
});
/**
* Some terminology which might be helpful...
*
*
* Client - This express app.
*
* This app is considered a "private client" because it can protect a secret
* server-side vs. a SPA/client-side app, for example, which cannot.
*
*
* Authorization Server - PingOne
*
* PingOne is the mutually trusted (by the user
* and the client) 3rd party handling authentication and authorization.
*
*
* Resource Owner - The authenticating user.
*
* The client requests access to some resource(s) that a user owns. The user
* authenticates and authorizes (or rejects) access access to the resource.
*
*
* OAuth 2.0 - The authorization framework.
*
* The OAuth 2.0 Authorization Code flow, is generally the flow to start with in
* order to comply with best practice.
*
*
* OIDC - The authentication framework.
*
* A layer on top of OAuth 2.0 which allows the client to know the identity of
* the user.
*/