Creating Offline First Native Web Applications using PouchDB and CouchDB and replication is a nice approach to remove the challenges keeping the client database insync with the server database.
One thing that always comes up is security, and security is very important and should not be taken lightly. Using implementations
like JWT or JsonWebToken and external authentication services like Auth0
and StormPath
can create a solid pattern to keep
your secrets off of your client.
Using JWT, when the user authenticates with the JWT Server, they receive a token, this token can be used to access the remote couchdb server or pouchdb server for replication. You can implement jwt support in couchdb itself or you can use a gateway.
A gateway will perform the jwt authentication and proxy to the server.
https://github.com/twilson63/express-pouchdb-jwt is a gateway microservice that will cache the remote server db on the app server, so that requests only have to go one way and the reads and writes are very fast.
You can setup one up in nodejs like so:
var app = express()
var corsSettings = cors({
origin: origin,
credentials: true
})
app.options('*', corsSettings)
app.use(corsSettings)
app.use(jwt({secret: new Buffer(process.env.JWT_SECRET, 'base64') }))
app.use('/', require('express-pouchdb')(MemPouchDB))
var local = MemPouchDB(localDb)
PouchDB.sync(local, remoteDb, {
live: true,
retry: true
})
app.listen(process.env.PORT || 8080)
By using a Auth Service and a Database Gateway, we can create a offline native app without having to store any secrets on the client.
When using a gateway server for pouchdb replication, it is important to setup your ajax headers to use the jwt token
remoteDb = PouchDB(event.object.remoteDb, {
ajax:{
headers: {
Authorization: 'Bearer ' + event.object.token
}
}
})
that looks great for authentication, but how would you suggest implementing an authorization layer, to make sure a user's access constraints? could you do some kind of filtered replication, based on (say) scope provided in the JWT? and how would you protect the data in the DB once it's replicated to the client (e.g., after token expiration / revocation, etc.)?