{"id":2367,"date":"2016-09-11T06:58:11","date_gmt":"2016-09-11T06:58:11","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2367"},"modified":"2025-10-09T07:06:24","modified_gmt":"2025-10-09T14:06:24","slug":"couchbase-mobile-v1-3-openid-connect","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/","title":{"rendered":"New in Couchbase Mobile v1.3: OpenID Connect"},"content":{"rendered":"<p><span style=\"color: #373737\">In this post I\u2019m going to write about an important new feature in\u00a0<\/span><a style=\"border: 0px\" href=\"https:\/\/www.couchbase.com\/developers\/mobile\/?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">Couchbase Mobile<\/a><span style=\"color: #373737\">\u00a0version 1.3,\u00a0<\/span><a style=\"border: 0px\" href=\"https:\/\/openid.net\/connect\/\">OpenID Connect<\/a><span style=\"color: #373737\">\u00a0(OIDC) support.<\/span><\/p>\n<p style=\"text-align: center\"><img decoding=\"async\" style=\"max-width: 400px ! important\" src=\"\/wp-content\/original-assets\/2016\/august\/couchbase-mobile-v1.3-openid-connect\/openid_connect_new-logo-1024x474.jpg\" alt=\"OpenID Connect Logo\" align=\"middle\" \/><\/p>\n<h2 style=\"border: 0px\">Introduction<\/h2>\n<p style=\"border: 0px\">Couchbase Mobile has an number of important security features. Sync Gateway acts as the intermediary that allows Couchbase Lite to replicate data to Couchbase Server. Naturally many applications want to authenticate users and control what they can do through Sync Gateway. OpenID Connect offers an option that simultaneously simplifies adding authentication, gives developers a big step up in integration options, and removes the headache of supporting the infrastructure needed.<\/p>\n<h2 style=\"border: 0px\">The Goal<\/h2>\n<p style=\"border: 0px\">Let me clarify a little. \u00a0In a typical scenario, an application uses Couchbase Lite as its primary data store. \u00a0Information gets read from and written to the local database. \u00a0The application sets up replication to a backend server through a Sync Gateway instance running in the cloud.<\/p>\n<p style=\"border: 0px\">Often, as the application developer, you want to tie data to a unique, verifiable identity. \u00a0Details of the identity don\u2019t really matter. \u00a0Managing the infrastructure becomes unnecessary overhead. \u00a0OpenID Connect provides the way to offload this to other trusted sources.<\/p>\n<p style=\"border: 0px\">Let\u2019s spell out all the actors. \u00a0We have the user, the application, Couchbase Lite (integrated in the application), our Sync Gateway instance, and OpendID Provider (OP).<\/p>\n<p style=\"border: 0px\">Sync Gateway controls authorizing any changes during replication. \u00a0The goal then, is to have the user log in on the application by authenticating themselves to the OP.\u00a0\u00a0\u00a0The OP provides information back the application can then use to provide\u00a0Sync Gateway proof of the user\u2019s identity. \u00a0We\u2019ll walk through all the steps for this.<\/p>\n<h2 style=\"border: 0px\">OpendID Connect<\/h2>\n<p style=\"border: 0px\">Many services already exist that require users to create an account and so on. \u00a0The\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/openid.net\/\">OpenID Foundation<\/a>\u00a0formed to build standards to open up the authentication portions of these systems to outside use. \u00a0This effort produced the OpenID Connect specification. \u00a0In the words of the OpenID Foundation:<\/p>\n<blockquote style=\"border-left-width: 0px;border-style: initial;border-color: initial;font-family: Georgia,\">\n<p style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin-bottom: 1.625em;vertical-align: baseline\"><a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/openid.net\/connect\/\">OpenID Connect<\/a>\u00a0is an interoperable authentication protocol based on the OAuth 2.0 family of specifications. It uses straightforward REST\/JSON message flows with a design goal of \u201cmaking simple things simple and complicated things possible\u201d. It\u2019s uniquely easy for developers to integrate, compared to any preceding Identity protocol.<\/p>\n<\/blockquote>\n<p style=\"border: 0px\">To find out more about OpenID Connect, you can take a look at the links above. \u00a0I also found\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/connect2id.com\/learn\/openid-connect\">this write-up<\/a>\u00a0valuable.<\/p>\n<h2 style=\"border: 0px\">Flows<\/h2>\n<p style=\"border: 0px\">OpenID Connect follows three possible \u201cflows\u201d. \u00a0A flow specifies the back and forth stages of the protocol, and all the details of what parameters are necessary and what they mean. \u00a0We\u2019ll talk about the Authorization Code Flow (auth flow) here. \u00a0The auth flow sets up refresh capabilities, so if you don\u2019t want to bother a user to sign in too often, it\u2019s the one to use.<\/p>\n<p style=\"border: 0px\">Couchbase has implemented classes to abstract out much of the complexity of OpendID Connect. \u00a0Like other parts of Couchbase Lite, the authentication classes handle a lot behind the scenes, especially the network calls.<\/p>\n<p style=\"border: 0px\">Still, a\u00a0full code sample is too much for one blog post. \u00a0I\u2019ll provide simplified examples. \u00a0To see a complete\u00a0application, take a look at the GrocerySync projects under\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/github.com\/couchbaselabs\">couchbaselabs<\/a>\u00a0on Github. \u00a0Here are links for\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/github.com\/couchbaselabs\/GrocerySync-Android\">Android<\/a>\u00a0and\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/github.com\/couchbaselabs\/Grocery-Sync-iOS\">iOS<\/a>. (Note as of this writing you need to switch to the openid branch.)<\/p>\n<p style=\"border: 0px\">Let\u2019s walk through the key steps in implementing authentication in an Android app. \u00a0We\u2019ll use Google as our OpenID Provider (OP).<\/p>\n<p style=\"border: 0px\">On Android, you can implement something directly, use the\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/developers.google.com\/identity\/\">Google Sign-In<\/a>\u00a0client library, or use the wrappers built into Couchbase Lite. \u00a0We\u2019ll use the Couchbase Lite wrappers. \u00a0To understand the underlying code better, you might want to check out Google\u2019s documentation on implementing OpenID Connect. \u00a0You can find it\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/developers.google.com\/identity\/protocols\/OpenIDConnect\">here<\/a>.<\/p>\n<h2 style=\"border: 0px\">Replication<\/h2>\n<p style=\"border: 0px\">In Couchbase, we refer to syncing database changes as replication. \u00a0No surprise then, that authentication ties deeply to replication. \u00a0Briefly, to sync, you create replication objects, set some options, then fire them up, either in one-shot or continuous mode.<\/p>\n<p style=\"border: 0px\">You typically do authentication by creating an\u00a0<code style=\"border: 0px;font-family: Monaco, Consolas,\">Authenticator<\/code>\u00a0object and assigning it to a Replication object. \u00a0Couchbase Lite has factories for creating different types of authenticators. \u00a0You can read more about replications,\u00a0<code style=\"border: 0px;font-family: Monaco, Consolas,\">Replication<\/code>\u00a0objects, and authenicators\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/current\/develop\/guides\/couchbase-lite\/native-api\/replication\/index.html\">here<\/a>.<\/p>\n<h2 style=\"border: 0px\">Code<\/h2>\n<p style=\"border: 0px\">In my simple example app, the first\u00a0<code style=\"border: 0px;font-family: Monaco, Consolas,\">Activity<\/code>\u00a0on launch presents two buttons, one to sign in, and one to sign out. \u00a0I\u2019ll refer to this as the main activity. \u00a0If the user isn\u2019t signed in, clicking the sign in button launches an activity with a web view to handle the sign in process. \u00a0I\u2019ll call that the login activity. \u00a0Storing the credentials happens after returning to the main activity.<\/p>\n<p style=\"border: 0px\">The code comprises three key sections, spread across these two activities.<\/p>\n<h3 style=\"border: 0px\">Prepare a Replication<\/h3>\n<p style=\"border: 0px\">Replications have a \u201cdirection\u201d. \u00a0A pull replication transfers data from a Sync Gateway, while a push sends data to one. \u00a0Here I just set up a pull replication, to highlight the authentication piece. \u00a0The code is broken out, but gets called during\u00a0<code style=\"border: 0px;font-family: Monaco, Consolas,\">onCreate<\/code>\u00a0in the main activity.<\/p>\n<pre class=\"lang:java decode:true \">private Replication pull;\r\n\r\nprivate void prepareToReplicate()  {\r\n    Database db = Runtime.getDb();\r\n\r\n    try {\r\n        pull = db.createPullReplication(new URL(Runtime.getSyncUrl()));\r\n    } catch (MalformedURLException ex) {\r\n        ex.printStackTrace();\r\n    }\r\n\r\n    pull.setContinuous(true);\r\n\r\n    Authenticator authenticator = OpenIDConnectAuthenticatorFactory\r\n            .createOpenIDConnectAuthenticator(new OIDCLoginCallback() {\r\n        @Override\r\n        public void callback(URL loginURL, URL redirectURL, OIDCLoginContinuation loginContinuation) {\r\n            MainActivity.this.loginContinuation = loginContinuation;\r\n\r\n            Intent loginIntent = new Intent(getApplicationContext(), Login.class);\r\n\r\n            loginIntent.putExtra(Login.LOGIN_URL_KEY, loginURL);\r\n            loginIntent.putExtra(Login.REDIRECT_URL_KEY, redirectURL);\r\n            startActivityForResult(loginIntent, LOGIN_REQUEST);\r\n        }\r\n    }, new AndroidContext(getApplicationContext()));\r\n\r\n    pull.setAuthenticator(authenticator);\r\n}<\/pre>\n<p style=\"border: 0px\">The critical part, for our purposes, lies in creating the authenticator. \u00a0Don\u2019t let the length of the code lines fool you. \u00a0It\u2019s all very straightforward. \u00a0It might help to examine the code from the inside out.<\/p>\n<p style=\"border: 0px\">Take a look at the body of the\u00a0<code style=\"border: 0px;font-family: Monaco, Consolas,\">callback<\/code>\u00a0method. \u00a0It takes three input parameters. \u00a0One it saves for later. \u00a0Two it puts into an\u00a0<code style=\"border: 0px;font-family: Monaco, Consolas,\">Intent<\/code>. \u00a0That intent kicks off the login activity and asks to receive a\u00a0result.<\/p>\n<p style=\"border: 0px\">All the formulating of the URLs the way OpenID needs them has been done for you. \u00a0For example, when I checked the loginURL, it was well over 400 characters long with what looked like more than 15 parameters! \u00a0Having implemented an OAuth 2 flow myself managing the network calls and all, I can definitely say this is a lot nicer.<\/p>\n<p style=\"border: 0px\">We\u2019ll see later how the Sync Gateway configuration feeds into this flow. \u00a0For the moment, if you do examine the URLs, know Sync Gateway supplies portions in response to the initial unauthenticated kick off of a replication.<\/p>\n<p style=\"border: 0px\">The third parameter to the callback method (the\u00a0<code style=\"border: 0px;font-family: Monaco, Consolas,\">OIDCLoginContinuation<\/code>\u00a0interface implementation) is supplied by Couchbase Lite. \u00a0This is the hook that you use to pass back the results of the sign on. \u00a0We\u2019ll explore it in more detail in a moment.<\/p>\n<h3 style=\"border: 0px\">Login Activity<\/h3>\n<p style=\"border: 0px\">As you can probably guess, many OpenID providers work off web pages. \u00a0The login activity consists of a standard web view. \u00a0(Using a web view has significant security implications. \u00a0Please see the special note at the end about security for details.) \u00a0You need to set up navigation and enable JavaScript. \u00a0You can read all about it in the\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/developer.android.com\/guide\/webapps\/webview.html\">Android Guide to building web apps<\/a>. \u00a0We only need to look at intercepting URL loading in detail. \u00a0Here\u2019s the code.<\/p>\n<pre class=\"lang:java decode:true \">private class LoginWebClient extends WebViewClient {\r\n    @Override\r\n    public boolean shouldOverrideUrlLoading(WebView view, String url) {\r\n        Uri uri = Uri.parse(url);\r\n\r\n        if (uri.getHost().contentEquals(redirectURL.getHost())) {\r\n            Intent response = new Intent();\r\n            response.setData(uri);\r\n            setResult(RESULT_OK, response);\r\n            finish();\r\n\r\n            return(true);  \/\/ true =&gt; application will handle this\r\n        }\r\n\r\n        return(false);  \/\/ Webview will load url\r\n    }\r\n}<\/pre>\n<p style=\"border: 0px\">(Note Android Studio may give you a warning about\u00a0<code style=\"border: 0px;font-family: Monaco, Consolas,\">shouldOverrideUrlLoading<\/code>\u00a0being deprecated. \u00a0As of this writing, this version is still the most widely supported.)<\/p>\n<p style=\"border: 0px\">When you supply a\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/developer.android.com\/guide\/webapps\/webview.html#HandlingNavigation\"><code style=\"border: 0px;font-family: Monaco, Consolas,\">WebViewClient<\/code><\/a>, Android uses it to hook all new page loads. \u00a0OpenID encodes the result of an authentication attempt in the form of a URL with, once again, a bunch of parameters embedded. \u00a0Our\u00a0<code style=\"border: 0px;font-family: Monaco, Consolas,\">WebViewClient<\/code>\u00a0waits to spot the redirect URL, packages that up, and ends the login activity, returning back to our main activity. \u00a0You may want to look into handling this with an AsyncTask to add extras like a progress bar.<\/p>\n<h3 style=\"border: 0px\">Finishing up<\/h3>\n<p style=\"border: 0px\">The login activity passes the response url back to the main\u00a0activity. \u00a0To complete the authentication process (including storing credentials), Couchbase Lite supplies its own callback, one that implements the\u00a0<code style=\"border: 0px;font-family: Monaco, Consolas,\">OIDCLoginContinuation<\/code>\u00a0interface. \u00a0The interface takes two arguments, the result url, and an exception. \u00a0The comments in the code snippet explain the semantics of the arguments, including how combinations of null and non-null values indicate success or other outcomes.<\/p>\n<pre class=\"lang:java decode:true \">@Override\r\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\r\n    if (LOGIN_REQUEST == requestCode) {\r\n        URL url = null;\r\n        Exception error = null;\r\n\r\n        if (RESULT_OK == resultCode) {\r\n            try {\r\n                String response = data.getData().toString();\r\n                url = new URL(response);\r\n            } catch (MalformedURLException ex) {\r\n                ex.printStackTrace();\r\n            }\r\n        }\r\n        else if (RESULT_CANCELED != resultCode) {\r\n            error = new Exception(\"Login failed.\");\r\n        }\r\n\r\n        \/\/ url = auth redirect =&gt; success\r\n        \/\/ url = null, ex = error =&gt; error\r\n        \/\/ url = null, ex = null =&gt; canceled\r\n        loginContinuation.callback(url, error);\r\n    }\r\n}<\/pre>\n<p style=\"border: 0px\">I handle errors simplistically for illustration. \u00a0You will likely want to do something more sophisticated. \u00a0The response url can contain error information if something goes wrong. \u00a0You can use that to give the user more detailed insight into what failed.<\/p>\n<h2 style=\"border: 0px\">App Code Summary<\/h2>\n<p style=\"border: 0px\">Using the Couchbase Lite classes, we have a very simple flow. \u00a0We set up an authenticator and attach it to a replication. \u00a0We start the replication, possibly in response to a user action (i.e. clicking the sign-in button).<\/p>\n<p style=\"border: 0px\">The authenticator hands us back control along with three pre-formed elements, two urls and a Couchbase Lite supplied callback. \u00a0We proceed with the authentication however we choose. \u00a0And, finally, we need to finish off by calling the callback we received.<\/p>\n<h2 style=\"border: 0px\">Tips and Tricks<\/h2>\n<h3 style=\"border: 0px\">User ID<\/h3>\n<p style=\"border: 0px\">We didn\u2019t show it in the code, but often you\u2019ll want to assign some kind of user id based on information in the OpenID response. \u00a0You can use the id to create a Sync Gateway channel to filter documents, for example.<\/p>\n<h3 style=\"border: 0px\">Signing out<\/h3>\n<p style=\"border: 0px\">You can clear the credentials from a replication by calling the<code style=\"border: 0px;font-family: Monaco, Consolas,\">clearAuthenticationStores<\/code>\u00a0method. \u00a0If you used a web view, you may also want to get rid of any session cookies. \u00a0This code snippet shows how to do that with Android API 21 or later.<\/p>\n<pre class=\"lang:java decode:true\">pull.clearAuthenticationStores();\r\nCookieManager.getInstance().removeAllCookies(null);\r\nCookieManager.getInstance().flush();<\/pre>\n<h3 style=\"border: 0px\">Testing<\/h3>\n<p style=\"border: 0px\">You can test your code using an emulator and a Sync Gateway instance running on the same machine. \u00a0Common emulators like the one supplied with Android or the one by Genymotion will allow you to connect to a service on your machine using a special IP address. \u00a0Google\u2019s OP will often reject these in urls, though. \u00a0I used a trick where Sync Gateway specifies localhost as its address. \u00a0Then in the\u00a0<code style=\"border: 0px;font-family: Monaco, Consolas,\">onActivityResult<\/code>\u00a0call, I substitute the IP address required by the emulator with this line:<\/p>\n<pre style=\"border: 0px\"><code class=\"java\" style=\"border: 0px;font-family: Monaco, Consolas,\">response = response.replaceFirst(Runtime.EMULATOR_HOST, Runtime.EMULATOR_IP);<\/code><\/pre>\n<h2 style=\"border: 0px\">Configuring Sync Gateway<\/h2>\n<p style=\"border: 0px\">We\u2019re done with the application code. \u00a0Let\u2019s take a brief look at configuring Sync Gateway to use OIDC. \u00a0This sample configuration shows how to configure GoogleAuthFlow as a provider. \u00a0You\u2019ll need to generate your own client_id and validation_key for production. \u00a0See the\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/developers.google.com\/identity\/protocols\/OAuth2\">Google documentation and links<\/a>\u00a0for details. \u00a0Find out more about Sync Gateway and how to configure it in the Couchbase documentation\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/current\/develop\/guides\/sync-gateway\/index.html\">here<\/a>.<\/p>\n<pre class=\"lang:default decode:true  \">{\r\n  \"log\": [\"*\"],\r\n  \"databases\": {\r\n    \"grocery-sync\": {\r\n      \"server\": \"walrus:.\",\r\n      \"users\": {\r\n        \"GUEST\": {\"disabled\": true}\r\n      },\r\n      \"unsupported\": {\r\n        \"oidc_test_provider\": {\r\n          \"enabled\": true\r\n        }  \r\n      },\r\n      \"oidc\": {\r\n        \"providers\": {\r\n            \"GoogleAuthFlow\": {\r\n                \"issuer\":\"https:\/\/accounts.google.com\",\r\n                \"client_id\":\"31919031332-8ea1795ckkphb7hmg6i4ul0blcpq8oq5.apps.googleusercontent.com\",\r\n                \"validation_key\":\"OCIbokd6-SE8LMZE_vQsq8F5\",\r\n                \"callback_url\":\"https:\/\/localhost:4984\/grocery-sync\/_oidc_callback\",\r\n                \"register\":true\r\n            }\r\n        },\r\n        \"default_provider\": \"GoogleAuthFlow\"\r\n      },\r\n      \"sync\": `\r\n        function(doc, oldDoc) {\r\n          var username = doc.owner;\r\n          if (!username)\r\n            username = oldDoc.owner;\r\n          if (!username)\r\n            throw({forbidden : \"item must have an owner\"});\r\n          var channelName = \"ch-\" + username;\r\n          access(username, channelName);\r\n          channel(channelName);\r\n        }\r\n      `\r\n    }\r\n  }\r\n}<\/pre>\n<h2 style=\"border: 0px\">Special Note \u2013 Security<\/h2>\n<p style=\"border: 0px\">In part, this blog outlines using a web view as part of the authentication process. \u00a0This approach has drawbacks, including the possibility that the app can eavesdrop on the authentication process. \u00a0For increased security, you may wish to consider using the system browser instead. \u00a0For more details, I recommend reading the latest version of this\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/tools.ietf.org\/html\/draft-ietf-oauth-native-apps-03\">IETF Internet-Draft<\/a>. \u00a0Security tends to be a moving target. \u00a0If you\u2019re dealing with highly sensitive information, take the time to read up on current best practices.<\/p>\n<h2 id=\"truepostscript\" style=\"border: 0px\">Postscript<\/h2>\n<div class=\"sectionbody\" style=\"border: 0px\">\n<div class=\"paragraph data-line-149\" style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;vertical-align: baseline\">\n<p style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin-bottom: 1.625em;vertical-align: baseline\">Check out more resources on our\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/www.couchbase.com\/developers\/community\/?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">developer portal<\/a>\u00a0and follow us on Twitter\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/twitter.com\/CouchbaseDev\">@CouchbaseDev<\/a>.<\/p>\n<p style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin-bottom: 1.625em;vertical-align: baseline\">You can post questions on our\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/www.couchbase.com\/forums\/?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">forums<\/a>. And we actively participate on\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/stackoverflow.com\/questions\/tagged\/couchbase\">Stack Overflow<\/a>.<\/p>\n<\/div>\n<div class=\"paragraph data-line-151\" style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;vertical-align: baseline\">\n<p style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin-bottom: 1.625em;vertical-align: baseline\">You can follow me personally at\u00a0<a style=\"border: 0px;font-family: inherit;font-style: inherit;font-weight: inherit;margin: 0px;padding: 0px;vertical-align: baseline;color: #1982d1;text-decoration: none\" href=\"https:\/\/twitter.com\/HodGreeley\">@HodGreeley<\/a><\/p>\n<\/div>\n<\/div>\n<p style=\"border: 0px\">\n","protected":false},"excerpt":{"rendered":"<p>In this post I\u2019m going to write about an important new feature in\u00a0Couchbase Mobile\u00a0version 1.3,\u00a0OpenID Connect\u00a0(OIDC) support. Introduction Couchbase Mobile has an number of important security features. Sync Gateway acts as the intermediary that allows Couchbase Lite to replicate data [&hellip;]<\/p>\n","protected":false},"author":73,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1810],"tags":[1713],"ppma_author":[9042],"class_list":["post-2367","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-mobile","tag-openid-connect"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>New in Couchbase Mobile v1.3: OpenID Connect - The Couchbase Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"New in Couchbase Mobile v1.3: OpenID Connect\" \/>\n<meta property=\"og:description\" content=\"In this post I\u2019m going to write about an important new feature in\u00a0Couchbase Mobile\u00a0version 1.3,\u00a0OpenID Connect\u00a0(OIDC) support. Introduction Couchbase Mobile has an number of important security features. Sync Gateway acts as the intermediary that allows Couchbase Lite to replicate data [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2016-09-11T06:58:11+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-10-09T14:06:24+00:00\" \/>\n<meta name=\"author\" content=\"Hod Greeley, Developer Advocate, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@HodGreeley\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Hod Greeley, Developer Advocate, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/\"},\"author\":{\"name\":\"Hod Greeley, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/9b62593c8a13531e53d52fcd5aabbca4\"},\"headline\":\"New in Couchbase Mobile v1.3: OpenID Connect\",\"datePublished\":\"2016-09-11T06:58:11+00:00\",\"dateModified\":\"2025-10-09T14:06:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/\"},\"wordCount\":1780,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"OpenID Connect\"],\"articleSection\":[\"Couchbase Mobile\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/\",\"name\":\"New in Couchbase Mobile v1.3: OpenID Connect - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2016-09-11T06:58:11+00:00\",\"dateModified\":\"2025-10-09T14:06:24+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"New in Couchbase Mobile v1.3: OpenID Connect\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/9b62593c8a13531e53d52fcd5aabbca4\",\"name\":\"Hod Greeley, Developer Advocate, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/21eb69cb5d4a401fb23b149e4f4e9e87\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g\",\"caption\":\"Hod Greeley, Developer Advocate, Couchbase\"},\"description\":\"Hod Greeley is a Developer Advocate for Couchbase, living in Silicon Valley. He has over two decades of experience as a software engineer and engineering manager. He has worked in a variety of software fields, including computational physics and chemistry, computer and network security, finance, and mobile. Prior to joining Couchbase in 2016, Hod led developer relations for mobile at Samsung. Hod holds a Ph.D. in chemical physics from Columbia University.\",\"sameAs\":[\"https:\/\/hod.greeley.org\/blog\",\"https:\/\/x.com\/HodGreeley\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/hod-greeley\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"New in Couchbase Mobile v1.3: OpenID Connect - The Couchbase Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/","og_locale":"en_US","og_type":"article","og_title":"New in Couchbase Mobile v1.3: OpenID Connect","og_description":"In this post I\u2019m going to write about an important new feature in\u00a0Couchbase Mobile\u00a0version 1.3,\u00a0OpenID Connect\u00a0(OIDC) support. Introduction Couchbase Mobile has an number of important security features. Sync Gateway acts as the intermediary that allows Couchbase Lite to replicate data [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/","og_site_name":"The Couchbase Blog","article_published_time":"2016-09-11T06:58:11+00:00","article_modified_time":"2025-10-09T14:06:24+00:00","author":"Hod Greeley, Developer Advocate, Couchbase","twitter_card":"summary_large_image","twitter_creator":"@HodGreeley","twitter_misc":{"Written by":"Hod Greeley, Developer Advocate, Couchbase","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/"},"author":{"name":"Hod Greeley, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/9b62593c8a13531e53d52fcd5aabbca4"},"headline":"New in Couchbase Mobile v1.3: OpenID Connect","datePublished":"2016-09-11T06:58:11+00:00","dateModified":"2025-10-09T14:06:24+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/"},"wordCount":1780,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["OpenID Connect"],"articleSection":["Couchbase Mobile"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/","url":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/","name":"New in Couchbase Mobile v1.3: OpenID Connect - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2016-09-11T06:58:11+00:00","dateModified":"2025-10-09T14:06:24+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-v1-3-openid-connect\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"New in Couchbase Mobile v1.3: OpenID Connect"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/9b62593c8a13531e53d52fcd5aabbca4","name":"Hod Greeley, Developer Advocate, Couchbase","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/21eb69cb5d4a401fb23b149e4f4e9e87","url":"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g","caption":"Hod Greeley, Developer Advocate, Couchbase"},"description":"Hod Greeley is a Developer Advocate for Couchbase, living in Silicon Valley. He has over two decades of experience as a software engineer and engineering manager. He has worked in a variety of software fields, including computational physics and chemistry, computer and network security, finance, and mobile. Prior to joining Couchbase in 2016, Hod led developer relations for mobile at Samsung. Hod holds a Ph.D. in chemical physics from Columbia University.","sameAs":["https:\/\/hod.greeley.org\/blog","https:\/\/x.com\/HodGreeley"],"url":"https:\/\/www.couchbase.com\/blog\/author\/hod-greeley\/"}]}},"authors":[{"term_id":9042,"user_id":73,"is_guest":0,"slug":"hod-greeley","display_name":"Hod Greeley, Developer Advocate, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g","author_category":"","last_name":"Greeley","first_name":"Hod","job_title":"","user_url":"https:\/\/hod.greeley.org\/blog","description":"Hod Greeley is a Developer Advocate for Couchbase, living in Silicon Valley. He has over two decades of experience as a software engineer and engineering manager. He has worked in a variety of software fields, including computational physics and chemistry, computer and network security, finance, and mobile. Prior to joining Couchbase in 2016, Hod led developer relations for mobile at Samsung. Hod holds a Ph.D. in chemical physics from Columbia University."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/2367","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/73"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=2367"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/2367\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=2367"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=2367"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=2367"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=2367"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}