mirror of https://gitee.com/bigwinds/arangodb
Added req.cookie and res.cookie helper methods to Foxx.
This commit is contained in:
parent
39ba358cd8
commit
251e046929
|
@ -32,13 +32,13 @@
|
||||||
|
|
||||||
!SECTION Documenting and constraining a specific route
|
!SECTION Documenting and constraining a specific route
|
||||||
|
|
||||||
If you now want to document your route, you can use JSDoc style comments (a
|
If you now want to document your route, you can use JSDoc style comments (a
|
||||||
multiline comment block with the first line starting with */*** instead
|
multiline comment block with the first line starting with */*** instead
|
||||||
of */**) above your routes to do that:
|
of */**) above your routes to do that:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
/** Get all foxxes
|
/** Get all foxxes
|
||||||
*
|
*
|
||||||
* If you want to get all foxxes, please use this
|
* If you want to get all foxxes, please use this
|
||||||
* method to do that.
|
* method to do that.
|
||||||
*/
|
*/
|
||||||
|
@ -47,11 +47,11 @@ app.get("/foxxes", function () {
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
The first line will be treated as a summary (For optical reasons in the
|
The first line will be treated as a summary (For optical reasons in the
|
||||||
produced documentation, the summary is restricted to 60 characters). All
|
produced documentation, the summary is restricted to 60 characters). All
|
||||||
following lines will be treated as additional notes shown in the detailed
|
following lines will be treated as additional notes shown in the detailed
|
||||||
view of the route documentation. With the provided information, Foxx will
|
view of the route documentation. With the provided information, Foxx will
|
||||||
generate a nice documentation for you. Furthermore you can describe your
|
generate a nice documentation for you. Furthermore you can describe your
|
||||||
API by chaining the following methods onto your path definition:
|
API by chaining the following methods onto your path definition:
|
||||||
|
|
||||||
!SUBSECTION Path Param
|
!SUBSECTION Path Param
|
||||||
|
@ -77,7 +77,7 @@ API by chaining the following methods onto your path definition:
|
||||||
!SUBSECTION onlyIfAuthenticated
|
!SUBSECTION onlyIfAuthenticated
|
||||||
<!-- js/server/modules/org/arangodb/foxx/request_context.js -->
|
<!-- js/server/modules/org/arangodb/foxx/request_context.js -->
|
||||||
@startDocuBlock JSF_foxx_RequestContext_onlyIfAuthenticated
|
@startDocuBlock JSF_foxx_RequestContext_onlyIfAuthenticated
|
||||||
|
|
||||||
!SECTION Documenting and constraining all routes
|
!SECTION Documenting and constraining all routes
|
||||||
|
|
||||||
In addition to documenting a specific route, you can also
|
In addition to documenting a specific route, you can also
|
||||||
|
@ -97,12 +97,12 @@ The following methods are available.
|
||||||
<!-- js/server/modules/org/arangodb/foxx/request_context.js -->
|
<!-- js/server/modules/org/arangodb/foxx/request_context.js -->
|
||||||
@startDocuBlock JSF_foxx_RequestContextBuffer_onlyIfAuthenticated
|
@startDocuBlock JSF_foxx_RequestContextBuffer_onlyIfAuthenticated
|
||||||
|
|
||||||
|
|
||||||
!SECTION Before and After Hooks
|
!SECTION Before and After Hooks
|
||||||
|
|
||||||
You can use the following two functions to do something before or respectively
|
You can use the following two functions to do something before or respectively
|
||||||
after the normal routing process is happening. You could use that for logging
|
after the normal routing process is happening. You could use that for logging
|
||||||
or to manipulate the request or response (translate it to a certain format for
|
or to manipulate the request or response (translate it to a certain format for
|
||||||
example).
|
example).
|
||||||
|
|
||||||
!SUBSECTION Before
|
!SUBSECTION Before
|
||||||
|
@ -120,14 +120,14 @@ example).
|
||||||
|
|
||||||
!SECTION The Request and Response Objects
|
!SECTION The Request and Response Objects
|
||||||
|
|
||||||
When you have created your FoxxController you can now define routes on it.
|
When you have created your FoxxController you can now define routes on it.
|
||||||
You provide each with a function that will handle the request. It gets two
|
You provide each with a function that will handle the request. It gets two
|
||||||
arguments (four, to be honest. But the other two are not relevant for now):
|
arguments (four, to be honest. But the other two are not relevant for now):
|
||||||
|
|
||||||
* The *request* object
|
* The *request* object
|
||||||
* The *response* object
|
* The *response* object
|
||||||
|
|
||||||
These objects are provided by the underlying ArangoDB actions and enhanced
|
These objects are provided by the underlying ArangoDB actions and enhanced
|
||||||
by the *BaseMiddleware* provided by Foxx.
|
by the *BaseMiddleware* provided by Foxx.
|
||||||
|
|
||||||
!SUBSECTION The Request Object
|
!SUBSECTION The Request Object
|
||||||
|
@ -136,7 +136,7 @@ The *request* object inherits several attributes from the underlying Actions:
|
||||||
|
|
||||||
* *compatibility*: an integer specifying the compatibility version sent by the
|
* *compatibility*: an integer specifying the compatibility version sent by the
|
||||||
client (in request header *x-arango-version*). If the client does not send this
|
client (in request header *x-arango-version*). If the client does not send this
|
||||||
header, ArangoDB will set this to the minimum compatible version number. The
|
header, ArangoDB will set this to the minimum compatible version number. The
|
||||||
value is 10000 * major + 100 * minor (e.g. *10400* for ArangoDB version 1.4).
|
value is 10000 * major + 100 * minor (e.g. *10400* for ArangoDB version 1.4).
|
||||||
|
|
||||||
* *user*: the name of the current ArangoDB user. This will be populated only
|
* *user*: the name of the current ArangoDB user. This will be populated only
|
||||||
|
@ -145,17 +145,17 @@ The *request* object inherits several attributes from the underlying Actions:
|
||||||
* *database*: the name of the current database (e.g. *_system*)
|
* *database*: the name of the current database (e.g. *_system*)
|
||||||
|
|
||||||
* *protocol*: *http* or *https*
|
* *protocol*: *http* or *https*
|
||||||
|
|
||||||
* *server*: a JSON object with sub-attributes *address* (containing server
|
* *server*: a JSON object with sub-attributes *address* (containing server
|
||||||
host name or IP address) and *port* (server port).
|
host name or IP address) and *port* (server port).
|
||||||
|
|
||||||
* *path*: request URI path, with potential [database name](../Glossary/README.html#database_name) stripped off.
|
* *path*: request URI path, with potential [database name](../Glossary/README.html#database_name) stripped off.
|
||||||
|
|
||||||
* *url*: request URI path + query string, with potential database name
|
* *url*: request URI path + query string, with potential database name
|
||||||
stripped off
|
stripped off
|
||||||
|
|
||||||
* *headers*: a JSON object with the request headers as key/value pairs
|
* *headers*: a JSON object with the request headers as key/value pairs
|
||||||
|
|
||||||
* *cookies*: a JSON object with the request cookies as key/value pairs
|
* *cookies*: a JSON object with the request cookies as key/value pairs
|
||||||
|
|
||||||
* *requestType*: the request method (e.g. "GET", "POST", "PUT", ...)
|
* *requestType*: the request method (e.g. "GET", "POST", "PUT", ...)
|
||||||
|
@ -183,6 +183,10 @@ convenience methods:
|
||||||
<!-- js/server/modules/org/arangodb/foxx/base_middleware.js -->
|
<!-- js/server/modules/org/arangodb/foxx/base_middleware.js -->
|
||||||
@startDocuBlock JSF_foxx_BaseMiddleware_request_params
|
@startDocuBlock JSF_foxx_BaseMiddleware_request_params
|
||||||
|
|
||||||
|
!SUBSECTION Cookie
|
||||||
|
<!-- js/server/modules/org/arangodb/foxx/base_middleware.js -->
|
||||||
|
@startDocuBlock JSF_foxx_BaseMiddleware_request_cookie
|
||||||
|
|
||||||
|
|
||||||
!SECTION The Response Object
|
!SECTION The Response Object
|
||||||
|
|
||||||
|
@ -202,41 +206,45 @@ You provide your response body as a string here.
|
||||||
!SUBSECTION Response Json
|
!SUBSECTION Response Json
|
||||||
<!-- js/server/modules/org/arangodb/foxx/base_middleware.js -->
|
<!-- js/server/modules/org/arangodb/foxx/base_middleware.js -->
|
||||||
@startDocuBlock JSF_foxx_BaseMiddleware_response_json
|
@startDocuBlock JSF_foxx_BaseMiddleware_response_json
|
||||||
|
|
||||||
|
!SUBSECTION Response Cookie
|
||||||
|
<!-- js/server/modules/org/arangodb/foxx/base_middleware.js -->
|
||||||
|
@startDocuBlock JSF_foxx_BaseMiddleware_response_cookie
|
||||||
|
|
||||||
!SECTION Controlling Access to Foxx Applications
|
!SECTION Controlling Access to Foxx Applications
|
||||||
|
|
||||||
Access to Foxx applications is controlled by the regular authentication mechanisms
|
Access to Foxx applications is controlled by the regular authentication mechanisms
|
||||||
present in ArangoDB. The server can be run with or without HTTP authentication.
|
present in ArangoDB. The server can be run with or without HTTP authentication.
|
||||||
|
|
||||||
If authentication is turned on,
|
If authentication is turned on,
|
||||||
then every access to the server is authenticated via HTTP authentication. This
|
then every access to the server is authenticated via HTTP authentication. This
|
||||||
includes Foxx applications. The global authentication can be toggled
|
includes Foxx applications. The global authentication can be toggled
|
||||||
via the configuration option.
|
via the configuration option.
|
||||||
|
|
||||||
If global HTTP authentication is turned on, requests to Foxx applications will
|
If global HTTP authentication is turned on, requests to Foxx applications will
|
||||||
require HTTP authentication too, and only valid users present in the *_users*
|
require HTTP authentication too, and only valid users present in the *_users*
|
||||||
system collection are allowed to use the applications.
|
system collection are allowed to use the applications.
|
||||||
|
|
||||||
Since ArangoDB 1.4, there is an extra option to restrict the authentication to
|
Since ArangoDB 1.4, there is an extra option to restrict the authentication to
|
||||||
just system API calls, such as */_api/...* and */_admin/...*. This option can be
|
just system API calls, such as */_api/...* and */_admin/...*. This option can be
|
||||||
turned on using the
|
turned on using the
|
||||||
"server.authenticate-system-only" configuration option. If it is turned on,
|
"server.authenticate-system-only" configuration option. If it is turned on,
|
||||||
then only system API requests need authentication whereas all requests to Foxx
|
then only system API requests need authentication whereas all requests to Foxx
|
||||||
applications and routes will not require authentication.
|
applications and routes will not require authentication.
|
||||||
|
|
||||||
This is recommended if you want to disable HTTP authentication for Foxx applications
|
This is recommended if you want to disable HTTP authentication for Foxx applications
|
||||||
but still want the general database APIs to be protected with HTTP authentication.
|
but still want the general database APIs to be protected with HTTP authentication.
|
||||||
|
|
||||||
If you need more fine grained control over the access to your Foxx application,
|
If you need more fine grained control over the access to your Foxx application,
|
||||||
we built an authentication system you can use. Currently we only support cookie-based
|
we built an authentication system you can use. Currently we only support cookie-based
|
||||||
authentication, but we will add the possibility to use Auth Tokens and external OAuth
|
authentication, but we will add the possibility to use Auth Tokens and external OAuth
|
||||||
providers in the near future. Of course you can roll your own authentication mechanism
|
providers in the near future. Of course you can roll your own authentication mechanism
|
||||||
if you want to, and you can do it in an application-specific way if required.
|
if you want to, and you can do it in an application-specific way if required.
|
||||||
|
|
||||||
To use the per-application authentication, you should first turn off the global
|
To use the per-application authentication, you should first turn off the global
|
||||||
HTTP authentication (or at least restrict it to system API calls as mentioned above).
|
HTTP authentication (or at least restrict it to system API calls as mentioned above).
|
||||||
Otherwise clients will need HTTP authentication and need additional authentication by
|
Otherwise clients will need HTTP authentication and need additional authentication by
|
||||||
your Foxx application.
|
your Foxx application.
|
||||||
|
|
||||||
To have global HTTP authentication turned on for system APIs but turned off for Foxx,
|
To have global HTTP authentication turned on for system APIs but turned off for Foxx,
|
||||||
your server startup parameters should look like this:
|
your server startup parameters should look like this:
|
||||||
|
@ -246,13 +254,13 @@ your server startup parameters should look like this:
|
||||||
**Note**: During development, you may even turn off HTTP authentication completely:
|
**Note**: During development, you may even turn off HTTP authentication completely:
|
||||||
|
|
||||||
--server.disable-authentication true --server.authenticate-system-only true
|
--server.disable-authentication true --server.authenticate-system-only true
|
||||||
|
|
||||||
Please keep in mind that turning HTTP authentication off completely will allow
|
Please keep in mind that turning HTTP authentication off completely will allow
|
||||||
unauthenticated access by anyone to all API functions, so do not use this is production.
|
unauthenticated access by anyone to all API functions, so do not use this is production.
|
||||||
|
|
||||||
Now it's time to configure the application-specific authentication. We built a small
|
Now it's time to configure the application-specific authentication. We built a small
|
||||||
[demo application](https://github.com/arangodb/foxx-authentication) to demonstrate how
|
[demo application](https://github.com/arangodb/foxx-authentication) to demonstrate how
|
||||||
this works.
|
this works.
|
||||||
|
|
||||||
To use the application-specific authentication in your own app, first activate it in your controller.
|
To use the application-specific authentication in your own app, first activate it in your controller.
|
||||||
|
|
||||||
|
|
|
@ -45,10 +45,61 @@ BaseMiddleware = function () {
|
||||||
trace,
|
trace,
|
||||||
_ = require("underscore"),
|
_ = require("underscore"),
|
||||||
console = require("console"),
|
console = require("console"),
|
||||||
|
crypto = require("org/arangodb/crypto"),
|
||||||
actions = require("org/arangodb/actions");
|
actions = require("org/arangodb/actions");
|
||||||
|
|
||||||
requestFunctions = {
|
requestFunctions = {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @startDocuBlock JSF_foxx_BaseMiddleware_request_cookie
|
||||||
|
///
|
||||||
|
/// `request.cookie(name, cfg)`
|
||||||
|
///
|
||||||
|
/// Read a cookie from the request. Optionally the cookie's signature can be verified.
|
||||||
|
///
|
||||||
|
/// *Parameter*
|
||||||
|
///
|
||||||
|
/// * *name*: the name of the cookie to read from the request.
|
||||||
|
/// * *cfg* (optional): an object with any of the following properties:
|
||||||
|
/// * *signed* (optional): an object with any of the following properties:
|
||||||
|
/// * *secret*: a secret string that was used to sign the cookie.
|
||||||
|
/// * *algorithm*: hashing algorithm that was used to sign the cookie. Default: *"sha256"*.
|
||||||
|
///
|
||||||
|
/// If *signed* is a string, it will be used as the *secret* instead.
|
||||||
|
///
|
||||||
|
/// If a *secret* is provided, a second cookie with the name *name + ".sig"* will
|
||||||
|
/// be read and its value will be verified as the cookie value's signature.
|
||||||
|
///
|
||||||
|
/// If the cookie is not set or its signature is invalid, "undefined" will be returned instead.
|
||||||
|
///
|
||||||
|
/// @EXAMPLES
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// var sid = request.cookie("sid", {signed: "keyboardcat"});
|
||||||
|
/// ```
|
||||||
|
/// @endDocuBlock
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
cookie: function (name, cfg) {
|
||||||
|
if (!cfg || typeof cfg !== 'object') {
|
||||||
|
cfg = {};
|
||||||
|
}
|
||||||
|
var value = this.cookies[name] || undefined;
|
||||||
|
if (value && cfg.signed) {
|
||||||
|
if (typeof cfg.signed === 'string') {
|
||||||
|
cfg.signed = {secret: cfg.signed};
|
||||||
|
}
|
||||||
|
var valid = crypto.constantEquals(
|
||||||
|
this.cookies[name + '.sig'] || '',
|
||||||
|
crypto.hmac(cfg.signed.secret, value, cfg.signed.algorithm)
|
||||||
|
);
|
||||||
|
if (!valid) {
|
||||||
|
value = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @startDocuBlock JSF_foxx_BaseMiddleware_request_body
|
/// @startDocuBlock JSF_foxx_BaseMiddleware_request_body
|
||||||
///
|
///
|
||||||
|
@ -102,6 +153,55 @@ BaseMiddleware = function () {
|
||||||
|
|
||||||
responseFunctions = {
|
responseFunctions = {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @startDocuBlock JSF_foxx_BaseMiddleware_response_cookie
|
||||||
|
///
|
||||||
|
/// `response.cookie(name, value, cfg)`
|
||||||
|
///
|
||||||
|
/// Add a cookie to the response. Optionally the cookie can be signed.
|
||||||
|
///
|
||||||
|
/// *Parameter*
|
||||||
|
///
|
||||||
|
/// * *name*: the name of the cookie to add to the response.
|
||||||
|
/// * *value*: the value of the cookie to add to the response.
|
||||||
|
/// * *cfg* (optional): an object with any of the following properties:
|
||||||
|
/// * *ttl* (optional): the number of seconds until this cookie expires.
|
||||||
|
/// * *path* (optional): the cookie path.
|
||||||
|
/// * *domain* (optional): the cookie domain.
|
||||||
|
/// * *secure* (optional): mark the cookie as safe transport (HTTPS) only.
|
||||||
|
/// * *httpOnly* (optional): mark the cookie as HTTP(S) only.
|
||||||
|
/// * *signed* (optional): an object with any of the following properties:
|
||||||
|
/// * *secret*: a secret string to sign the cookie with.
|
||||||
|
/// * *algorithm*: hashing algorithm to sign the cookie with. Default: *"sha256"*.
|
||||||
|
///
|
||||||
|
/// If *signed* is a string, it will be used as the *secret* instead.
|
||||||
|
///
|
||||||
|
/// If a *secret* is provided, a second cookie with the name *name + ".sig"* will
|
||||||
|
/// be added to the response, containing the cookie's HMAC signature.
|
||||||
|
///
|
||||||
|
/// @EXAMPLES
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// response.cookie("sid", "abcdef", {signed: "keyboardcat"});
|
||||||
|
/// ```
|
||||||
|
/// @endDocuBlock
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
cookie: function (name, value, cfg) {
|
||||||
|
if (!cfg || typeof cfg !== 'object') {
|
||||||
|
cfg = {ttl: cfg};
|
||||||
|
}
|
||||||
|
var ttl = (typeof cfg.ttl === 'number' && cfg.ttl !== Infinity) ? cfg.ttl : undefined;
|
||||||
|
actions.addCookie(this, name, value, ttl, cfg.path, cfg.domain, cfg.secure, cfg.httpOnly);
|
||||||
|
if (cfg.signed) {
|
||||||
|
if (typeof cfg.signed === 'string') {
|
||||||
|
cfg.signed = {secret: cfg.signed};
|
||||||
|
}
|
||||||
|
var sig = crypto.hmac(cfg.signed.secret, value, cfg.signed.algorithm);
|
||||||
|
actions.addCookie(this, name + '.sig', sig, ttl, cfg.path, cfg.domain, cfg.secure, cfg.httpOnly);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @startDocuBlock JSF_foxx_BaseMiddleware_response_status
|
/// @startDocuBlock JSF_foxx_BaseMiddleware_response_status
|
||||||
///
|
///
|
||||||
|
|
Loading…
Reference in New Issue