9.2.12. Authentication¶
Interfaces for obtaining session and authorization data.
Note
We’re also strongly recommend you to setup SSL to improve all authentication methods security.
Basic Authentication¶
Basic authentication (RFC 2617) is a quick and simple way to authenticate with CouchDB. The main drawback is the need to send user credentials with each request which may be insecure and could hurt operation performance (since CouchDB must compute password hash with every request):
Request:
GET / HTTP/1.1
Accept: application/json
Authorization: Basic cm9vdDpyZWxheA==
Host: localhost:5984
Response:
HTTP/1.1 200 OK
Cache-Control: must-revalidate
Content-Length: 177
Content-Type: application/json
Date: Mon, 03 Dec 2012 00:44:47 GMT
Server: CouchDB (Erlang/OTP)
{
"couchdb":"Welcome",
"uuid":"0a959b9b8227188afc2ac26ccdf345a6",
"version":"1.3.0",
"vendor": {
"version":"1.3.0",
"name":"The Apache Software Foundation"
}
}
Cookie Authentication¶
For cookie authentication (RFC 2109) CouchDB generates a token that the
client can use for the next few requests to CouchDB. Tokens are valid until
a timeout. When CouchDB sees a valid token in a subsequent request, it will
authenticate user by this token without requesting the password again. By
default, cookies are valid for 10 minutes, but it’s adjustable
. Also it’s possible to make cookies
persistent
To obtain the first token and thus authenticate a user for the first time, the username and password must be sent to the _session API.
/_session
¶
-
POST
/_session
¶ Initiates new session for specified user credentials by providing Cookie value.
Request Headers: - Content-Type –
- application/x-www-form-urlencoded
- application/json
Query Parameters: - next (string) – Enforces redirect after successful login to the specified location. This location is relative from server root. Optional.
Form Parameters: - name – User name
- password – Password
Response Headers: - Set-Cookie – Authorization token
Response JSON Object: - ok (boolean) – Operation status
- name (string) – Username
- roles (array) – List of user roles
Status Codes: - 200 OK – Successfully authenticated
- 302 Found – Redirect after successful authentication
- 401 Unauthorized – Username or password wasn’t recognized
Request:
POST /_session HTTP/1.1 Accept: application/json Content-Length: 24 Content-Type: application/x-www-form-urlencoded Host: localhost:5984 name=root&password=relax
It’s also possible to send data as JSON:
POST /_session HTTP/1.1 Accept: application/json Content-Length: 37 Content-Type: application/json Host: localhost:5984 { "name": "root", "password": "relax" }
Response:
HTTP/1.1 200 OK Cache-Control: must-revalidate Content-Length: 43 Content-Type: application/json Date: Mon, 03 Dec 2012 01:23:14 GMT Server: CouchDB (Erlang/OTP) Set-Cookie: AuthSession=cm9vdDo1MEJCRkYwMjq0LO0ylOIwShrgt8y-UkhI-c6BGw; Version=1; Path=/; HttpOnly {"ok":true,"name":"root","roles":["_admin"]}
If
next
query parameter was provided the response will trigger redirection to the specified location in case of successful authentication:Request:
POST /_session?next=/blog/_design/sofa/_rewrite/recent-posts HTTP/1.1 Accept: application/json Content-Type: application/x-www-form-urlencoded Host: localhost:5984 name=root&password=relax
Response:
HTTP/1.1 302 Moved Temporarily Cache-Control: must-revalidate Content-Length: 43 Content-Type: application/json Date: Mon, 03 Dec 2012 01:32:46 GMT Location: http://localhost:5984/blog/_design/sofa/_rewrite/recent-posts Server: CouchDB (Erlang/OTP) Set-Cookie: AuthSession=cm9vdDo1MEJDMDEzRTp7Vu5GKCkTxTVxwXbpXsBARQWnhQ; Version=1; Path=/; HttpOnly {"ok":true,"name":null,"roles":["_admin"]}
- Content-Type –
-
GET
/_session
¶ Returns complete information about authenticated user. This information contains User Context Object, authentication method and available ones and authentication database.
Query Parameters: - basic (boolean) – Accept Basic Auth by requesting this resource. Optional.
Status Codes: - 200 OK – Successfully authenticated.
- 401 Unauthorized – Username or password wasn’t recognized.
Request:
GET /_session HTTP/1.1 Host: localhost:5984 Accept: application/json Cookie: AuthSession=cm9vdDo1MEJDMDQxRDpqb-Ta9QfP9hpdPjHLxNTKg_Hf9w
Response:
HTTP/1.1 200 OK Cache-Control: must-revalidate Content-Length: 175 Content-Type: application/json Date: Fri, 09 Aug 2013 20:27:45 GMT Server: CouchDB (Erlang/OTP) Set-Cookie: AuthSession=cm9vdDo1MjA1NTBDMTqmX2qKt1KDR--GUC80DQ6-Ew_XIw; Version=1; Path=/; HttpOnly { "info": { "authenticated": "cookie", "authentication_db": "_users", "authentication_handlers": [ "oauth", "cookie", "default" ] }, "ok": true, "userCtx": { "name": "root", "roles": [ "_admin" ] } }
-
DELETE
/_session
¶ Closes user’s session.
Status Codes: - 200 OK – Successfully close session.
- 401 Unauthorized – User wasn’t authenticated.
Request:
DELETE /_session HTTP/1.1 Accept: application/json Cookie: AuthSession=cm9vdDo1MjA1NEVGMDo1QXNQkqC_0Qmgrk8Fw61_AzDeXw Host: localhost:5984
Response:
HTTP/1.1 200 OK Cache-Control: must-revalidate Content-Length: 12 Content-Type: application/json Date: Fri, 09 Aug 2013 20:30:12 GMT Server: CouchDB (Erlang/OTP) Set-Cookie: AuthSession=; Version=1; Path=/; HttpOnly { "ok": true }
Proxy Authentication¶
Note
To use this authentication method make sure that the
{couch_httpd_auth, proxy_authentication_handler}
value in added to
the list of the active httpd/authentication_handlers
:
[httpd]
authentication_handlers = {couch_httpd_oauth, oauth_authentication_handler}, {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, proxy_authentication_handler}, {couch_httpd_auth, default_authentication_handler}
Proxy authentication is very useful in case your application already uses some external authentication service and you don’t want to duplicate users and their roles in CouchDB.
This authentication method allows creation of a User Context Object for remotely authenticated user. By default, the client just need to pass specific headers to CouchDB with related request:
X-Auth-CouchDB-UserName
: username;X-Auth-CouchDB-Roles
: list of user roles separated by a comma (,
);X-Auth-CouchDB-Token
: authentication token. Optional, but strongly recommended toforce token be required
to prevent requests from untrusted sources.
Request:
GET /_session HTTP/1.1
Host: localhost:5984
Accept: application/json
Content-Type: application/json; charset=utf-8
X-Auth-CouchDB-Roles: users,blogger
X-Auth-CouchDB-UserName: foo
Response:
HTTP/1.1 200 OK
Cache-Control: must-revalidate
Content-Length: 190
Content-Type: application/json
Date: Fri, 14 Jun 2013 10:16:03 GMT
Server: CouchDB (Erlang/OTP)
{
"info": {
"authenticated": "proxy",
"authentication_db": "_users",
"authentication_handlers": [
"oauth",
"cookie",
"proxy",
"default"
]
},
"ok": true,
"userCtx": {
"name": "foo",
"roles": [
"users",
"blogger"
]
}
}
Note that you don’t need to request session to be authenticated by this method if all required HTTP headers are provided.
OAuth Authentication¶
CouchDB supports OAuth 1.0 authentication (RFC 5849). OAuth provides a method for clients to access server resources without sharing real credentials (username and password).
First, configure oauth, by setting consumer and token with their secrets and binding token to real CouchDB username.
Probably, it’s not good idea to work with plain curl, let use some scripting language like Python:
#!/usr/bin/env python2
from oauth import oauth # pip install oauth
import httplib
URL = 'http://localhost:5984/_session'
CONSUMER_KEY = 'consumer1'
CONSUMER_SECRET = 'sekr1t'
TOKEN = 'token1'
SECRET = 'tokensekr1t'
consumer = oauth.OAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET)
token = oauth.OAuthToken(TOKEN, SECRET)
req = oauth.OAuthRequest.from_consumer_and_token(
consumer,
token=token,
http_method='GET',
http_url=URL,
parameters={}
)
req.sign_request(oauth.OAuthSignatureMethod_HMAC_SHA1(), consumer,token)
headers = req.to_header()
headers['Accept'] = 'application/json'
con = httplib.HTTPConnection('localhost', 5984)
con.request('GET', URL, headers=headers)
resp = con.getresponse()
print resp.read()
or Ruby:
#!/usr/bin/env ruby
require 'oauth' # gem install oauth
URL = 'http://localhost:5984'
CONSUMER_KEY = 'consumer1'
CONSUMER_SECRET = 'sekr1t'
TOKEN = 'token1'
SECRET = 'tokensekr1t'
@consumer = OAuth::Consumer.new CONSUMER_KEY,
CONSUMER_SECRET,
{:site => URL}
@access_token = OAuth::AccessToken.new(@consumer, TOKEN, SECRET)
puts @access_token.get('/_session').body
Both snippets produces similar request and response pair:
GET /_session HTTP/1.1
Host: localhost:5984
Accept: application/json
Authorization: OAuth realm="", oauth_nonce="81430018", oauth_timestamp="1374561749", oauth_consumer_key="consumer1", oauth_signature_method="HMAC-SHA1", oauth_version="1.0", oauth_token="token1", oauth_signature="o4FqJ8%2B9IzUpXH%2Bk4rgnv7L6eTY%3D"
HTTP/1.1 200 OK
Cache-Control : must-revalidate
Content-Length : 167
Content-Type : application/json
Date : Tue, 23 Jul 2013 06:51:15 GMT
Server: CouchDB (Erlang/OTP)
{
"ok": true,
"info": {
"authenticated": "oauth",
"authentication_db": "_users",
"authentication_handlers": ["oauth", "cookie", "default"]
},
"userCtx": {
"name": "couchdb_username",
"roles": []
}
}
There we request the _session resource to ensure that authentication was successful and the target CouchDB username is correct. Change the target URL to request required resource.