I'm new to CouchApp and CouchDB and have some questions.
How can I make sessions in CouchApp from my own database (not _users)?
How would I retrieve that session?
How can I parse data from a document?
I can do it with a view, but when someone calls my view url and gets the id, he can get all data like passwords (I'm trying to use my own database to store login information).
In my database I have a document like this:
{
"_id": "...",
"_rev": "...",
"XDocType": "user",
"name": "Administrator",
"password": "1234",
"username": "admin"
}
I want to make a simple login/register/logout with sessions, not cookies.
A session is less important with a Couch app because the whole application runs in the client (browser). CouchDB only does the following:
Authentication (user can connect with a password, or get a cookie to identify later)
Authorization (CouchDB will allow or disallow reading or writing data, depending on the user's name and roles, and the database _security object and validate_doc_update functions.
You can change the default database for user accounts (instead of _users) however you must always have a users database. You can set the _security of the database so that anonymous users cannot access it. (However new users cannot easily sign-up, so it is a trade-off.)
Jan has an excellent post about CouchDB security.
Related
I have a link that contains a parameter token which is the JWT token that will be validated across another domain. I'm struggling with the fact that a user can copy and share that link across several browsers or with other users.
The jwt payload looks like the following:
{
"userId": "46",
"role": "User",
"nbf": 1589877059,
"exp": 1589963459,
"iat": 1589877059
}
My goal is to secure that link from being shared other than the current user while authenticating that user on the second domain.
Am i missing something or is there any other way to secure a link across different domains? Any suggestion is really appreciated.
Update
An approach I'm trying is storing the last active SessionId in the database and validating it on both sides. In case the token is valid and actual SessionId is different from the last active id, then redirect to some unauthorized page. but the drawback is that the user will require session-authentication instead of cookie authentication since the session will reset each time the user closes the browser but the cookie will remain the same.
I'm setting up a document esigning process using Docusign. Since we have multiple associations, We have setup multiple accounts (around 20 APIAccountID under one organization (or you can say as one INTEGRATOR_KEY_ID)) one for each association. Can someone please let me know on how do we switch to different APIAccountID based on the request we get. Also, is it the right way to create a new DocuSignConnection every time when we get the request for different association ?
Your integration should use just one INTEGRATOR_KEY for the entire integration. When using one of the DocuSign OAuth flows such as JWT as you mention.
After the user grants access by providing their credentials and clicking Accept an access token will be sent back to your app (at the redirect URI you specify on your integrator key).
You then use that access token to call the User Info API which will return account ID for that given user.
User Info API
Request:
Authorization: Bearer eyJ0eX...MrhIddzBAQ
GET https://account-d.docusign.com/oauth/userinfo
Response:
{
"sub": "4799e5e9-1559-4915-9862-cf4713bbcacc",
"name": "Susan Smart",
"given_name": "Susan",
"family_name": "Smart",
"created": "2015-08-13T22:03:03.45",
"email": "susan.smart#example.com",
"accounts": [
{
"account_id": "a4ec37d6-04aa-4f37-86c2-143885c220e1",
"is_default": true,
"account_name": "Susan Smart",
"base_uri": "https://domain.example.com",
"organization": {
"organization_id": "9c5fb8e1-b0bf-4970-8e0e-054ff8a249bf",
"links": [
{
"rel": "self",
"href": "https://account.domain.example.com/organizations/9c5fb8e1-b0bf-4970-8e0e-054ff8a249bf"
}
]
}
}
]
}
You have one application which sends signing requests on behalf of multiple associations (organizations)?
As Ergin says, your application will have one integration key which will be used for all associations.
When a human logs into you app using OAuth Auth Code Grant, your app receives an access token. You can use that access token to look up the user's account and site (API URL).
Your application can make sending requests for any number of people and their associations. Each API request includes the user's individual access token, their account_id, and uses the site data to create the URL.
HTH.
I'm working on a CouchDB backend that will exist as a central store for a React app using PouchDB. Reading the docs on the security section: http://docs.couchdb.org/en/2.1.1/intro/security.html, one does not need an admin account or a user account of any kind to create user records. Now, they wouldn't be able to create any documents, as I have admin party disabled. But I also don't want an open API end point to allow just anyone to write data. Is there a way for me to restrict this?
I've tried to see if I could setup a security document like so:
curl -X PUT http://admin:admin#localhost:5984/_users/_security -d '{"admins":{"names":[],"roles":[]},"members":{"names":[],"roles":[]}}'
But I'm still able to add users:
curl -X PUT http://localhost:5984/_users/org.couchdb.user:abc1 -d '{"name":"abc1", "password":"abc1", "roles":[], "type":"user"}'
Is there something I can change so I cannot do a put request to the couchdb.users namespace without admin credentials?
You are setting no admins or users in your security document and a database with no members allows any user to write regular documents, same as default behaviour.
Try to set your server's admin as _users database admin, i.e. change the security document to -d '{"admins": { "names": ["admin"], "roles": [] }, "members": { "names": [], "roles": [] }}' or even better create an admin role and assign it to a separate CouchDB user for more granular control.
I need my API to return objects that contain some user info. For example:
api/comment/123 needs to return:
{
id: 123,
author: {
id: 'googleblahblah|123456789',
name: 'James Bond'
}
}
Normally I would just join the user and the comment table, though in this case I can't. My app's database stores the user id, though the name (and other user stuff) is stored in Auth0.
Obviously making an API call to Auth0 to 'enrich' objects on every API call is not plausible.
Do I cache all / some some user info on my app server? Have only the user ID in the API result and let the client enrich the data?
How do people handle this?
I do not think there is an ultimate solution for this problem.
What I did was creating a user table with user id and user name in my own database. Whenever somebody logs via Auth0 in I would create or update the logged-in user information in that table with the OAuth token information.
After that you could join the tables as you stated.
I am building an app using Loopback API that will be consumed by an iPhone APP. There is a connection to a MySQL database where I run some queries to get some results and expose on the API.
The endpoints contain an ACL that will allow only authenticated users to perform any operation, including the GET ones. So basically the requests need to be done using the ?access_token query string.
I want to set a token that can be saved on the MySQL database and can be used "forever" on the API.
I am not sure if I am asking the right question but if this is not the way to solve this problem, what would it be?
My main point is that I need the requests to be authenticated with a token but I don't want to lose this token once it's set.
Any help is appreciated. Thanks!
By default the max token ttl is 1 year. Thankfully Loopback has an option that will allow you to create a permanent access token:
allowEternalTokens Boolean Allow access tokens that never expire.
https://loopback.io/doc/en/lb3/Model-definition-JSON-file.html#advanced-options
If you're using the default user model, you can enable it in server/model-config.json:
"User": {
"dataSource": "db",
"options": {
"validateUpsert": true,
"allowEternalTokens": true
}
},
Then when logging in, set ttl to -1.
Note that every time you log in (User.login) your token will be replaced with a new one. So if you want to reuse the same access token, log in only once. You can get the existing access token from the AccessToken model (or directly from the database).
If you have a custom user model, you can set allowEternalTokens directly in the model definition file. In addition, if you have a custom user model you'll also need to update the relations of the AccessToken model (either the built-in one or your custom one if you have it) to point to the custom user model.
More info on custom user/access token models here: http://loopback.io/doc/en/lb3/Authentication-authorization-and-permissions.html#preparing-access-control-models
You can pass the ttl in the credential json sent by you iOS app, in this example the token will live for 60sec, just use a high value for make a token "permanent":
POST /Users/login
{
"email":"user#email.com",
"password":"12345689",
"ttl": 60000
}
Or create a before remote method to change the ttl propertie, check this article:
LINK
I set the TTL to the max 1 year but I set the created field to some time very far in the future such as 2112-10-29 00:00:00-04. This makes the token expire a century from now.