Authentication - Registration and Login
The Realm Object Server chooses not to intrude on your own authentication mechanism. However do support one right out of the box, Anonymous Authentication!
We have removed the concept of login vs register in favor of just login!
We hope that you find our login functionality both robust and flexible enough for any situation. ROS now gives you full control to do things like send confirmation emails, define custom flows, with your own login flow use existing 3rd party SDKs with ease.
Anonymous Authentication
By default, authentication is completely off allowing for anonymous authentication. If a client downloads your app and attempts to connect without a user, the SDK would create a random GUID of the user and store it in the device's keychain for subsequent use. If the user deletes the app, then the anonymous user will exist indefinitely in the system but would be unable to login with the previous anonymous credentials.
For example in the Swift Code you may see:
let config = Realm.Sync.Configuration(url: URL(string: "localhost:9080"), user: nil))
let realm = try! Realm(config: config)
SyncUser.anonymousLogin {err, user) in
print("\(SyncUser.current.identity)" // an new userId will be created if the keychain value doesn't exist
}
To disable this set a configuration value of disableAnonymousAuthentication to true
const ros = new ROS({
//... other config values
disableAnonymousAuthentication: true
})
Custom Authentication
To enable custom authentication create a login function on your ROS instance's configuration value. This will also disable anonymous authentication.
const ros = new ROS({
... other configs
login: function(payload, done){
//payload is just an arbitrary JSON
//call done with an error type and this login will be rejected on the client side
done(new Error('bad login'))
//call done with a object with userId and that user and the login will be established
done({
userId: 'max'
})
//you can even choose to add other arbitrary data, but userId must exist
done({
userId: 'max',
otherData: {
email: '[email protected]',
birthday: '1/2/1992'
}
}
}
})
Example using Facebook Authentication
Once you've gotten a hold of your users Facebook Access Token from the FBLoginKit SDK you can then submit
let facebookAccessToken
Sync.User.login([
"facebookAccessToken": "facebookAccessToken"
], { (err, userReponse) in
if err {
fatalError("Oh no! \(err.localizedDescription())"
}else {
print("userId: \(userResponse.user.userId)") // the user object is a SyncUser
print("fullJSONPayload: \(userResponse.json)") // this will contain any other json data returned
}
})
In your server you can implement the following function for login.
const Realm = require('realm')
const FacebookSDK = require('facebook')
const realm = new Realm()
var loginFunction = function(payload, done) {
FacebookSDK(payload.facebookAccessToken)
.then(facebookResponse => {
const users = realm.objects('User').filter(`facebookUserId == ${facebookResponse.facebookUserId}`)
if(users.length != 1) {
done(new Error("User with facebookUserId ", facebookResponse.facebookUserId, "doesn't exist")
}else {
const foundUser = users[0]
done({
userId: foundUser,
facebookInfo: facebookResponse
})
}
})
.catch(done)
}
Registration
The login function is also used for registration! The most important thing is that calling done with a userId that doesn't exist will create a valid SyncUser instance and will register it internally within Realm Object Server
Using the example above, we can "create" a new user if it doesn't exist.
const Realm = require('realm')
const FacebookSDK = require('facebook')
const realm = new Realm()
var loginFunction = function(payload, done) {
FacebookSDK(payload.facebookAccessToken)
.then(facebookResponse => {
const users = realm.objects('User').filter(`facebookUserId == ${facebookResponse.facebookUserId}`)
if(users.length != 1) {
// we have a valid facebook User but we don't have him/her in our system
var createdUser = null
realm.write(() => {
createdUser = realm.create('User', {
_id: uuid.v4(),
facebookUserId: facebookResponse.facebookUserId,
birthday: facebookResponse.birthday,
friendList: facebookResponse.friendList
})
})
done({
userId: createdUser,
facebookInfo: facebookResponse
})
}else {
const foundUser = users[0]
done({
userId: foundUser,
facebookInfo: facebookResponse
})
}
})
.catch(done)
}