{"__v":35,"_id":"562586b423053b2300f5972e","category":{"project":"53fe6dc5addab8973c1af267","version":"53fe6dc5addab8973c1af26a","_id":"564fb3a59b4fab1700187518","pages":[],"__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-11-20T23:58:29.588Z","from_sync":false,"order":1,"slug":"integration-guide","title":"Integration Guide"},"parentDoc":null,"project":"53fe6dc5addab8973c1af267","user":"53fe70beaddab8973c1af273","version":{"__v":19,"_id":"53fe6dc5addab8973c1af26a","project":"53fe6dc5addab8973c1af267","createdAt":"2014-08-27T23:46:13.941Z","releaseDate":"2014-08-27T23:46:13.941Z","categories":["53fe6dc5addab8973c1af26b","53fe71a2addab8973c1af276","53fe7d89addab8973c1af2b0","53fe7d8daddab8973c1af2b1","53fe836faddab8973c1af2ce","53ff9a4823a37e1d5cebafe1","53ff9e3723a37e1d5cebaff7","53ffaca523a37e1d5cebb039","53ffad2e23a37e1d5cebb03c","5400c7d2ec93b29b61d4f7be","5400f0e1ec93b29b61d4f7dd","54d5636323010a0d001aca81","54d565c1276f8e0d00feab54","54ff40532882a10d00546927","556606d25561af0d008208b7","558c91900b236c2500d37c9a","56180a14f8c9632100ac7599","564fb3a59b4fab1700187518","5702e2d2f2d6f336005e901f"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"1.0.0","version":"1.0"},"updates":["5661cb5baa6a760d005e82c6"],"next":{"pages":[],"description":""},"createdAt":"2015-10-20T00:11:32.594Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":2,"body":"[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"Tutorial Requirements\",\n  \"body\": \"In order to finish this tutorial, you'll need to have handled [registering users](doc:register-new-users) who come through Clef and [logging them in](doc:log-your-users-in).\"\n}\n[/block]\nSo, you're registering and logging in new users who come through Clef — what about users who already have an account on your website? \n\nIf a user who already has an account on your website wants to use Clef, you need to provide a way for them to **link their existing account with their Clef ID** when they're already logged in. The best place to do this is within a settings dashboard on your website.\n\n# Connecting users in a settings dashboard\n\nFirst, we'll add a \"Connect with Clef\" button to your settings dashboard. The best place to add this button is in an \"Account settings\" tab, or in the same place where you let users reset passwords. We've made it really easy to add this button — in your HTML, insert the following script tag:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<script type=\\\"text/javascript\\\" src=\\\"https://clef.io/v3/clef.js\\\" \\n        class=\\\"clef-button\\\"\\n        data-app-id=\\\"{{ YOUR_APP_ID }}\\\" \\n        data-color=\\\"blue\\\" \\n        data-style=\\\"flat\\\"\\n        data-state=\\\"{{ A_STATE_PARAMETER }}\\\"\\n        data-redirect-url=\\\"http://yourwebsite.com/clef/connect\\\" \\n        data-type=\\\"connect\\\">\\n</script>\",\n      \"language\": \"html\"\n    }\n  ]\n}\n[/block]\nThis will create a button that looks like this: \n[block:html]\n{\n  \"html\": \"<iframe src=\\\"https://clef.io/iframes/button?type=connect\\\"\\n        width=\\\"100%\\\" height=\\\"38px\\\" style=\\\"border:none; overflow:hidden;\\\"\\n        />\"\n}\n[/block]\nYou'll notice the script tag above is the same as the one we use for [adding the login button](http://docs.getclef.com/v1.0/docs/register-new-users#section-adding-the-clef-button-to-your-site), with 2 differences. `data-type` is `connect` instead of `login` (which changes the appearance), and `data-redirect-url` points to a different endpoint that we haven't created yet. \n\nLet's create that endpoint now. In the endpoint, we'll be handling the Clef authentication handshake, and then **associating the returned Clef ID with the user already in your session**. Like we did when [logging your users in](doc:log-your-users-in), we'll use Clef's API libraries to make this easy: \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \":::at:::app.route('/clef/connect')\\ndef clef_connect_endpoint():\\n  # Query your database for the user who is *already logged \\n  # in to your website*\\n  user = get_user_by_user_id(session.get('user_id'))\\n  \\n  # Get the state parameter passed as a query arg and verify it\\n\\tstate = request.args.get('state')\\n\\tassert_state_is_valid(state)\\n\\n\\t# Get the authorization code passed as a query arg\\n\\tcode = request.args.get('code')\\n\\ttry:\\n\\t  user_information = clef.get_login_information(code=code)\\n\\texcept clef.APIError, e:\\n  \\t# An error occurred while trying to get user information\\n\\t  abort(500)\\n\\t\\n  # Now, set the returned clef ID on the user, linking them \\n  # to their Clef account\\n  user.clef_id = user_information['id']\\n  user.save()\\n  \\n  flash('You linked your Clef account!')\\n  return redirect(url_for('settings'))\",\n      \"language\": \"javascript\"\n    },\n    {\n      \"code\": \"app.get('/clef/connect', function clefConnectEndpoint(req, res) {\\n \\t// Query your database for the user who is *already logged \\n  // in to your website*\\n\\tUser.findById(req.session.userId).then(function(user) {\\n    var state = req.query.state;\\n    assertStateParameterIsValid(req.session, state);\\n\\n    // Get the authorization code passed as a query arg\\n    var code = req.query.code;\\n    clef.getLoginInformation({code: code}, function(err, userInformation) {\\n        if (err) {\\n            // An error occurred while trying to get user information\\n        } else {\\n          \\t// Now, set the returned clef ID on the user, linking them \\n  \\t\\t\\t\\t\\t// to their Clef account\\n            var clefID = userInformation['id'];\\n            user.clefID = clefID;\\n            user.save();\\n            req.flash('info', 'You linked your Clef account!');\\n            res.redirect('/settings');\\n        }\\n    });\\n  });\\n}\\n\",\n      \"language\": \"javascript\",\n      \"name\": \"Node\"\n    },\n    {\n      \"code\": \"<?php\\n\\t// In your clef_connect endpoint: \\n\\tsession_start()\\n  session_regenerate_id(true);\\n\\n \\t// Query your database for the user who is *already logged \\n  // in to your website*\\n\\t$user = get_from_user_id($_SESSION['user_id']);\\n\\n  \\\\Clef\\\\Clef::initialize(APP_ID, APP_SECRET);\\n\\n  // Get the state parameter passed as a query arg and verify it\\n  assert_state_is_valid($_GET[\\\"state\\\"]);\\n\\n  // Get user information using the authorization code passed as a query arg\\n  try {\\n    $response = \\\\Clef\\\\Clef::get_login_information($_GET[\\\"code\\\"]);\\n    $user_information = $response->info;\\n  } catch (Exception $e) {\\n    // An error occurred while trying to get user information\\n    echo \\\"Connect with Clef failed: \\\" . $e->getMessage();\\n  }\\n\\n  // Now, set the returned clef ID on the user, linking them \\n  // to their Clef account\\n\\t$user->clef_id = $user_information['id'];\\n\\tsave_user_in_db($user);\\n\\n\\theader(\\\"Location: settings.php\\\");\\n\\tdie();\\n?>\",\n      \"language\": \"php\"\n    }\n  ]\n}\n[/block]\nIn `clef_connect_endpoint`, we first look up the user in the current session. Then, we perform Clef's authentication handshake. After that, we set their `clef_id` to the `id` passed back from Clef. Finally, we redirect back to the settings dashboard.\n\n# Detecting an existing user by their email address\n\nWe've provided a way for existing users to connect their Clef accounts, but what happens when an existing user tries to log in using Clef without having already connected their account? \n\nIf you're storing email addresses, you can query your database using the email address we pass to you in `user_information`. If you find a matching user, you can associate the Clef ID you get from the handshake with that user. In the redirect URL endpoint you created to [register new users](doc:register-new-users), change the code to look like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"clef_id = user_information['id']\\nemail_address = user_information['email']\\n\\n# As before, query by clef_id first\\nuser = User.query.filter_by(clef_id=clef_id).first()\\nif not user:\\n  # If there's no user, try querying by email and linking with Clef\\n  user = User.query.filter_by(email=email_address).first()\\n  if user:\\n    user.clef_id = clef_id\\n  # Otherwise, create a new user\\n\\telse:\\n\\t  user = create_user_from_clef(user_information)\",\n      \"language\": \"python\"\n    },\n    {\n      \"code\": \"var clefID = userInformation['id'];\\nvar email = userInformation['email'];\\n\\n// Query by clef_id first\\nUser.find({ \\n  where: { clefID: clefID } \\n}).then(function(maybeUser) {\\n  // If there's no user, try querying by email\\n  if (!maybeUser) {\\n    return User.find({ where: { email: email } });\\n  }\\n  return maybeUser;\\n}).then(function(maybeUser) {\\n  // If there's still no user, create one\\n  if (!maybeUser) {\\n    return User.create({ where: { clefID: clefID, email: email } });\\n  }\\n  return maybeUser;\\n}).then(function(user) {\\n  // Make sure the user is linked with this Clef ID\\n  user.clefID = clefID;\\n  user.save();\\n  \\n  // Now log the user in and redirect them\\n});\",\n      \"language\": \"javascript\",\n      \"name\": \"Node\"\n    },\n    {\n      \"code\": \"<?php\\n\\n// As before, query by clef_id first\\n$user = get_user_from_clef_id($user_information->id);\\nif (!$user) {\\n  // If there's no user, try querying by email and linking with Clef\\n  $user = get_user_by_email($user_information->email);\\n  if ($user) {\\n  \\t$user.clef_id = $user_information->id;\\n    save_user($user);\\n  }\\n  // Otherwise, create a new user\\n \\telse {\\n  \\t$user = insert_user($user_information->id, $user_information->email); \\n  }\\n}\\n\\n?>\",\n      \"language\": \"php\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"In order to get an email back from `user_information`, you should make sure that you've toggled email as a piece of requested piece of information from users. You can do this in the \\\"Permissions\\\" tab in the [developer dashboard](https://getclef.com/user/login).\",\n  \"title\": \"\"\n}\n[/block]\n# Next up\n\nCongrats! You've now let your existing users start using Clef. \n\nNext, you'll need to handle clearing users' sessions when they log out on their phones. Check out our guide on [logging users out](doc:log-your-users-out) . \n[block:html]\n{\n  \"html\": \"<div></div>\\n<a class=\\\"clef-button blue\\\" href=\\\"/v1.0/docs/log-your-users-out\\\">See \\\"Log your users out\\\"</a>\\n<style></style>\"\n}\n[/block]","excerpt":"In this tutorial, you'll learn how to let existing users link their account on your website with Clef. If you need help after reading this, chat live with our developers in Clef's [community room](http://community.getclef.com).","slug":"connect-existing-users","type":"basic","title":"Connect existing users"}

Connect existing users

In this tutorial, you'll learn how to let existing users link their account on your website with Clef. If you need help after reading this, chat live with our developers in Clef's [community room](http://community.getclef.com).

[block:callout] { "type": "warning", "title": "Tutorial Requirements", "body": "In order to finish this tutorial, you'll need to have handled [registering users](doc:register-new-users) who come through Clef and [logging them in](doc:log-your-users-in)." } [/block] So, you're registering and logging in new users who come through Clef — what about users who already have an account on your website? If a user who already has an account on your website wants to use Clef, you need to provide a way for them to **link their existing account with their Clef ID** when they're already logged in. The best place to do this is within a settings dashboard on your website. # Connecting users in a settings dashboard First, we'll add a "Connect with Clef" button to your settings dashboard. The best place to add this button is in an "Account settings" tab, or in the same place where you let users reset passwords. We've made it really easy to add this button — in your HTML, insert the following script tag: [block:code] { "codes": [ { "code": "<script type=\"text/javascript\" src=\"https://clef.io/v3/clef.js\" \n class=\"clef-button\"\n data-app-id=\"{{ YOUR_APP_ID }}\" \n data-color=\"blue\" \n data-style=\"flat\"\n data-state=\"{{ A_STATE_PARAMETER }}\"\n data-redirect-url=\"http://yourwebsite.com/clef/connect\" \n data-type=\"connect\">\n</script>", "language": "html" } ] } [/block] This will create a button that looks like this: [block:html] { "html": "<iframe src=\"https://clef.io/iframes/button?type=connect\"\n width=\"100%\" height=\"38px\" style=\"border:none; overflow:hidden;\"\n />" } [/block] You'll notice the script tag above is the same as the one we use for [adding the login button](http://docs.getclef.com/v1.0/docs/register-new-users#section-adding-the-clef-button-to-your-site), with 2 differences. `data-type` is `connect` instead of `login` (which changes the appearance), and `data-redirect-url` points to a different endpoint that we haven't created yet. Let's create that endpoint now. In the endpoint, we'll be handling the Clef authentication handshake, and then **associating the returned Clef ID with the user already in your session**. Like we did when [logging your users in](doc:log-your-users-in), we'll use Clef's API libraries to make this easy: [block:code] { "codes": [ { "code": "@app.route('/clef/connect')\ndef clef_connect_endpoint():\n # Query your database for the user who is *already logged \n # in to your website*\n user = get_user_by_user_id(session.get('user_id'))\n \n # Get the state parameter passed as a query arg and verify it\n\tstate = request.args.get('state')\n\tassert_state_is_valid(state)\n\n\t# Get the authorization code passed as a query arg\n\tcode = request.args.get('code')\n\ttry:\n\t user_information = clef.get_login_information(code=code)\n\texcept clef.APIError, e:\n \t# An error occurred while trying to get user information\n\t abort(500)\n\t\n # Now, set the returned clef ID on the user, linking them \n # to their Clef account\n user.clef_id = user_information['id']\n user.save()\n \n flash('You linked your Clef account!')\n return redirect(url_for('settings'))", "language": "javascript" }, { "code": "app.get('/clef/connect', function clefConnectEndpoint(req, res) {\n \t// Query your database for the user who is *already logged \n // in to your website*\n\tUser.findById(req.session.userId).then(function(user) {\n var state = req.query.state;\n assertStateParameterIsValid(req.session, state);\n\n // Get the authorization code passed as a query arg\n var code = req.query.code;\n clef.getLoginInformation({code: code}, function(err, userInformation) {\n if (err) {\n // An error occurred while trying to get user information\n } else {\n \t// Now, set the returned clef ID on the user, linking them \n \t\t\t\t\t// to their Clef account\n var clefID = userInformation['id'];\n user.clefID = clefID;\n user.save();\n req.flash('info', 'You linked your Clef account!');\n res.redirect('/settings');\n }\n });\n });\n}\n", "language": "javascript", "name": "Node" }, { "code": "<?php\n\t// In your clef_connect endpoint: \n\tsession_start()\n session_regenerate_id(true);\n\n \t// Query your database for the user who is *already logged \n // in to your website*\n\t$user = get_from_user_id($_SESSION['user_id']);\n\n \\Clef\\Clef::initialize(APP_ID, APP_SECRET);\n\n // Get the state parameter passed as a query arg and verify it\n assert_state_is_valid($_GET[\"state\"]);\n\n // Get user information using the authorization code passed as a query arg\n try {\n $response = \\Clef\\Clef::get_login_information($_GET[\"code\"]);\n $user_information = $response->info;\n } catch (Exception $e) {\n // An error occurred while trying to get user information\n echo \"Connect with Clef failed: \" . $e->getMessage();\n }\n\n // Now, set the returned clef ID on the user, linking them \n // to their Clef account\n\t$user->clef_id = $user_information['id'];\n\tsave_user_in_db($user);\n\n\theader(\"Location: settings.php\");\n\tdie();\n?>", "language": "php" } ] } [/block] In `clef_connect_endpoint`, we first look up the user in the current session. Then, we perform Clef's authentication handshake. After that, we set their `clef_id` to the `id` passed back from Clef. Finally, we redirect back to the settings dashboard. # Detecting an existing user by their email address We've provided a way for existing users to connect their Clef accounts, but what happens when an existing user tries to log in using Clef without having already connected their account? If you're storing email addresses, you can query your database using the email address we pass to you in `user_information`. If you find a matching user, you can associate the Clef ID you get from the handshake with that user. In the redirect URL endpoint you created to [register new users](doc:register-new-users), change the code to look like this: [block:code] { "codes": [ { "code": "clef_id = user_information['id']\nemail_address = user_information['email']\n\n# As before, query by clef_id first\nuser = User.query.filter_by(clef_id=clef_id).first()\nif not user:\n # If there's no user, try querying by email and linking with Clef\n user = User.query.filter_by(email=email_address).first()\n if user:\n user.clef_id = clef_id\n # Otherwise, create a new user\n\telse:\n\t user = create_user_from_clef(user_information)", "language": "python" }, { "code": "var clefID = userInformation['id'];\nvar email = userInformation['email'];\n\n// Query by clef_id first\nUser.find({ \n where: { clefID: clefID } \n}).then(function(maybeUser) {\n // If there's no user, try querying by email\n if (!maybeUser) {\n return User.find({ where: { email: email } });\n }\n return maybeUser;\n}).then(function(maybeUser) {\n // If there's still no user, create one\n if (!maybeUser) {\n return User.create({ where: { clefID: clefID, email: email } });\n }\n return maybeUser;\n}).then(function(user) {\n // Make sure the user is linked with this Clef ID\n user.clefID = clefID;\n user.save();\n \n // Now log the user in and redirect them\n});", "language": "javascript", "name": "Node" }, { "code": "<?php\n\n// As before, query by clef_id first\n$user = get_user_from_clef_id($user_information->id);\nif (!$user) {\n // If there's no user, try querying by email and linking with Clef\n $user = get_user_by_email($user_information->email);\n if ($user) {\n \t$user.clef_id = $user_information->id;\n save_user($user);\n }\n // Otherwise, create a new user\n \telse {\n \t$user = insert_user($user_information->id, $user_information->email); \n }\n}\n\n?>", "language": "php" } ] } [/block] [block:callout] { "type": "info", "body": "In order to get an email back from `user_information`, you should make sure that you've toggled email as a piece of requested piece of information from users. You can do this in the \"Permissions\" tab in the [developer dashboard](https://getclef.com/user/login).", "title": "" } [/block] # Next up Congrats! You've now let your existing users start using Clef. Next, you'll need to handle clearing users' sessions when they log out on their phones. Check out our guide on [logging users out](doc:log-your-users-out) . [block:html] { "html": "<div></div>\n<a class=\"clef-button blue\" href=\"/v1.0/docs/log-your-users-out\">See \"Log your users out\"</a>\n<style></style>" } [/block]