Changed how paths are handled by server.js, to more closely match the Angular
dev environment. New paths: /api/login: redirects to SSO /api: all calls (other than above) are sent to cloudapi /: static content served from static/ All API calls to cloudapi now pass through server.js's HTTP /api, not /. The static/static path is now gone, since it was causing too much trouble. static/ is now a symlink directly to app/dist, which is where a fresh Angular build appears when app/ is built.
This commit is contained in:
parent
18d35b5172
commit
8672439358
35
README.md
35
README.md
@ -25,46 +25,39 @@ The SSH key used must be the correct format, e.g. generated with:
|
|||||||
|
|
||||||
# Endpoints
|
# Endpoints
|
||||||
|
|
||||||
## GET /static/*
|
## GET /*
|
||||||
|
|
||||||
This is where all the front-end code goes. All files will be served as-is as
|
This is where all the front-end code goes. All files will be served as-is as
|
||||||
found in that directory. The default is static/index.html. There is no
|
found in that directory (by default a symlink to app/dist). The default is
|
||||||
authentication; all files are public.
|
static/index.html. There is no authentication; all files are public.
|
||||||
|
|
||||||
## GET /login
|
## GET /api/login
|
||||||
|
|
||||||
Call this endpoint to begin the login cycle. It will redirect you to the SSO
|
Call this endpoint to begin the login cycle. It will redirect you to the SSO
|
||||||
login page: an HTTP 302, with a Location header.
|
login page: an HTTP 302, with a Location header.
|
||||||
|
|
||||||
## GET /token
|
## GET/POST/PUT/DELETE/HEAD /api/*
|
||||||
|
|
||||||
Upon successful login, the SSO login page will redirect to this endpoint. This
|
All calls will be passed through to cloudapi. For these calls to succeed,
|
||||||
endpoint will return a 204, along with a X-Auth-Token header that must be saved
|
they MUST provide an X-Auth-Token header, containing the token returned from
|
||||||
by the front-end code. All subsequent calls should provide this X-Auth-Token
|
SSO.
|
||||||
header.
|
|
||||||
|
|
||||||
## Other
|
|
||||||
|
|
||||||
All other calls will be passed through to cloudapi. For these calls to succeed,
|
|
||||||
they MUST provide the X-Auth-Token header that the /token endpoint returns.
|
|
||||||
|
|
||||||
# Interaction cycle
|
# Interaction cycle
|
||||||
|
|
||||||
client --- GET /login --------> this server
|
client --- GET /api/login --------> this server
|
||||||
<-- 302 Location #1 ----
|
<-- 302 Location #1 ----
|
||||||
|
|
||||||
client --- GET <Location #1> --> SSO server
|
client --- GET <Location #1> --> SSO server
|
||||||
<separate SSO cycle>
|
<separate SSO cycle>
|
||||||
<-- 302 Location #2 ----
|
<-- 302 with token query arg
|
||||||
|
|
||||||
client --- GET <Location #2> --> this server
|
|
||||||
<-- 204 X-Auth-Token ----
|
|
||||||
|
|
||||||
From now on call this server as if it were a cloudapi server (using [cloudapi
|
From now on call this server as if it were a cloudapi server (using [cloudapi
|
||||||
paths](https://github.com/joyent/sdc-cloudapi/blob/master/docs/index.md#api-introduction)),
|
paths](https://github.com/joyent/sdc-cloudapi/blob/master/docs/index.md#api-introduction)),
|
||||||
always providing the X-Auth-Token. For example, to retrieve a list of packages:
|
except prefixing any path with "/api". Also always provide the X-Auth-Token.
|
||||||
|
|
||||||
client --- GET /my/packages --> this server
|
For example, to retrieve a list of packages:
|
||||||
|
|
||||||
|
client --- GET /api/my/packages --> this server
|
||||||
<-- 200 JSON body ------
|
<-- 200 JSON body ------
|
||||||
|
|
||||||
The most useful cloudapi endpoints to begin with will be ListPackages,
|
The most useful cloudapi endpoints to begin with will be ListPackages,
|
||||||
|
@ -15,6 +15,10 @@ let CLOUDAPI = {};
|
|||||||
let CLOUDAPI_HOST = '';
|
let CLOUDAPI_HOST = '';
|
||||||
let SIGNER = {};
|
let SIGNER = {};
|
||||||
|
|
||||||
|
const LOGIN_PATH = '/api/login';
|
||||||
|
const API_PATH = '/api'; // all calls here go to cloudapi
|
||||||
|
const API_RE = new RegExp('^' + API_PATH + '/');
|
||||||
|
const STATIC_RE = new RegExp('^/');
|
||||||
|
|
||||||
// Take any HTTP request that has a token, sign that request with an
|
// Take any HTTP request that has a token, sign that request with an
|
||||||
// HTTP-Signature header, and pass it along to cloudapi. Return any response
|
// HTTP-Signature header, and pass it along to cloudapi. Return any response
|
||||||
@ -40,16 +44,19 @@ function proxy(req, res, cb) {
|
|||||||
|
|
||||||
// check the X-Auth-Token is present
|
// check the X-Auth-Token is present
|
||||||
if (req.header('X-Auth-Token') == undefined) {
|
if (req.header('X-Auth-Token') == undefined) {
|
||||||
res.send({"Error": "X-Auth-Token header missing"});
|
res.send({'Error': 'X-Auth-Token header missing'});
|
||||||
res.send(401);
|
res.send(401);
|
||||||
return cb();
|
return cb();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// strip off /api from path before forwarding to cloudapi
|
||||||
|
let url = req.url.substr(API_PATH.length);
|
||||||
|
|
||||||
// sign the request before forwarding to cloudapi
|
// sign the request before forwarding to cloudapi
|
||||||
let headers = req.headers;
|
let headers = req.headers;
|
||||||
var rs = mod_sdcauth.requestSigner({ sign: SIGNER });
|
var rs = mod_sdcauth.requestSigner({ sign: SIGNER });
|
||||||
headers.date = rs.writeDateHeader();
|
headers.date = rs.writeDateHeader();
|
||||||
rs.writeTarget(req.method, req.url);
|
rs.writeTarget(req.method, url);
|
||||||
|
|
||||||
rs.sign(function signedCb(err, authz) {
|
rs.sign(function signedCb(err, authz) {
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -60,10 +67,12 @@ function proxy(req, res, cb) {
|
|||||||
headers.authorization = authz;
|
headers.authorization = authz;
|
||||||
|
|
||||||
const opts = {
|
const opts = {
|
||||||
path: req.url,
|
path: url,
|
||||||
headers: headers
|
headers: headers
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.dir(opts);
|
||||||
|
|
||||||
// make the call to cloudapi
|
// make the call to cloudapi
|
||||||
switch (req.method) {
|
switch (req.method) {
|
||||||
case 'GET': CLOUDAPI.get(opts, proxyReturn); break;
|
case 'GET': CLOUDAPI.get(opts, proxyReturn); break;
|
||||||
@ -153,20 +162,21 @@ function main() {
|
|||||||
server.use(mod_restify.authorizationParser());
|
server.use(mod_restify.authorizationParser());
|
||||||
server.use(mod_restify.bodyReader());
|
server.use(mod_restify.bodyReader());
|
||||||
|
|
||||||
// where to server static content from
|
// login path is /api/login
|
||||||
server.get(/^\/static.*/, mod_restify.plugins.serveStatic({
|
server.get(LOGIN_PATH, login);
|
||||||
|
|
||||||
|
// all cloudapi calls are proxied through /api
|
||||||
|
server.get(API_RE, proxy);
|
||||||
|
server.put(API_RE, proxy);
|
||||||
|
server.del(API_RE, proxy);
|
||||||
|
server.post(API_RE, proxy);
|
||||||
|
server.head(API_RE, proxy);
|
||||||
|
|
||||||
|
// where to serve static content from
|
||||||
|
server.get(STATIC_RE, mod_restify.plugins.serveStatic({
|
||||||
directory: 'static',
|
directory: 'static',
|
||||||
default: 'index.html'
|
default: 'index.html'
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// route HTTP requests to proper functions
|
|
||||||
server.get('/login', login);
|
|
||||||
|
|
||||||
server.get(/^/, proxy);
|
|
||||||
server.put(/^/, proxy);
|
|
||||||
server.del(/^/, proxy);
|
|
||||||
server.post(/^/, proxy);
|
|
||||||
server.head(/^/, proxy);
|
|
||||||
|
|
||||||
// enable HTTP server
|
// enable HTTP server
|
||||||
server.listen(CONFIG.server.port, function listening() {
|
server.listen(CONFIG.server.port, function listening() {
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
<html>
|
|
||||||
<body>
|
|
||||||
Hi!
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1 +0,0 @@
|
|||||||
.
|
|
Reference in New Issue
Block a user