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
|
||||
|
||||
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
|
||||
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
|
||||
of */**) above your routes to do that:
|
||||
|
||||
```js
|
||||
/** Get all foxxes
|
||||
*
|
||||
*
|
||||
* If you want to get all foxxes, please use this
|
||||
* 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
|
||||
produced documentation, the summary is restricted to 60 characters). All
|
||||
following lines will be treated as additional notes shown in the detailed
|
||||
view of the route documentation. With the provided information, Foxx will
|
||||
generate a nice documentation for you. Furthermore you can describe your
|
||||
The first line will be treated as a summary (For optical reasons in the
|
||||
produced documentation, the summary is restricted to 60 characters). All
|
||||
following lines will be treated as additional notes shown in the detailed
|
||||
view of the route documentation. With the provided information, Foxx will
|
||||
generate a nice documentation for you. Furthermore you can describe your
|
||||
API by chaining the following methods onto your path definition:
|
||||
|
||||
!SUBSECTION Path Param
|
||||
|
@ -77,7 +77,7 @@ API by chaining the following methods onto your path definition:
|
|||
!SUBSECTION onlyIfAuthenticated
|
||||
<!-- js/server/modules/org/arangodb/foxx/request_context.js -->
|
||||
@startDocuBlock JSF_foxx_RequestContext_onlyIfAuthenticated
|
||||
|
||||
|
||||
!SECTION Documenting and constraining all routes
|
||||
|
||||
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 -->
|
||||
@startDocuBlock JSF_foxx_RequestContextBuffer_onlyIfAuthenticated
|
||||
|
||||
|
||||
|
||||
!SECTION Before and After Hooks
|
||||
|
||||
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
|
||||
or to manipulate the request or response (translate it to a certain format for
|
||||
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
|
||||
or to manipulate the request or response (translate it to a certain format for
|
||||
example).
|
||||
|
||||
!SUBSECTION Before
|
||||
|
@ -120,14 +120,14 @@ example).
|
|||
|
||||
!SECTION The Request and Response Objects
|
||||
|
||||
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
|
||||
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
|
||||
arguments (four, to be honest. But the other two are not relevant for now):
|
||||
|
||||
* The *request* 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.
|
||||
|
||||
!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
|
||||
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).
|
||||
|
||||
* *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*)
|
||||
|
||||
* *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).
|
||||
|
||||
* *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
|
||||
|
||||
* *headers*: a JSON object with the request headers 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", ...)
|
||||
|
@ -183,6 +183,10 @@ convenience methods:
|
|||
<!-- js/server/modules/org/arangodb/foxx/base_middleware.js -->
|
||||
@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
|
||||
|
||||
|
@ -202,41 +206,45 @@ You provide your response body as a string here.
|
|||
!SUBSECTION Response Json
|
||||
<!-- js/server/modules/org/arangodb/foxx/base_middleware.js -->
|
||||
@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
|
||||
|
||||
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.
|
||||
|
||||
If authentication is turned on,
|
||||
then every access to the server is authenticated via HTTP authentication. This
|
||||
includes Foxx applications. The global authentication can be toggled
|
||||
If authentication is turned on,
|
||||
then every access to the server is authenticated via HTTP authentication. This
|
||||
includes Foxx applications. The global authentication can be toggled
|
||||
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*
|
||||
system collection are allowed to use the applications.
|
||||
|
||||
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
|
||||
turned on using the
|
||||
"server.authenticate-system-only" configuration option. If it is turned on,
|
||||
then only system API requests need authentication whereas all requests to Foxx
|
||||
applications and routes will not require authentication.
|
||||
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
|
||||
turned on using the
|
||||
"server.authenticate-system-only" configuration option. If it is turned on,
|
||||
then only system API requests need authentication whereas all requests to Foxx
|
||||
applications and routes will not require authentication.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
authentication, but we will add the possibility to use Auth Tokens and external OAuth
|
||||
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
|
||||
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.
|
||||
|
||||
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
|
||||
your Foxx application.
|
||||
your Foxx application.
|
||||
|
||||
To have global HTTP authentication turned on for system APIs but turned off for Foxx,
|
||||
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:
|
||||
|
||||
--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.
|
||||
|
||||
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
|
||||
this works.
|
||||
this works.
|
||||
|
||||
To use the application-specific authentication in your own app, first activate it in your controller.
|
||||
|
||||
|
|
|
@ -45,10 +45,61 @@ BaseMiddleware = function () {
|
|||
trace,
|
||||
_ = require("underscore"),
|
||||
console = require("console"),
|
||||
crypto = require("org/arangodb/crypto"),
|
||||
actions = require("org/arangodb/actions");
|
||||
|
||||
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
|
||||
///
|
||||
|
@ -102,6 +153,55 @@ BaseMiddleware = function () {
|
|||
|
||||
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
|
||||
///
|
||||
|
|
Loading…
Reference in New Issue