{"_id":"5614781f91fe0f1900927445","category":{"_id":"564fb3a59b4fab1700187518","version":"53fe6dc5addab8973c1af26a","project":"53fe6dc5addab8973c1af267","__v":0,"pages":[],"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-11-20T23:58:29.588Z","from_sync":false,"order":1,"slug":"integration-guide","title":"Integration Guide"},"version":{"_id":"53fe6dc5addab8973c1af26a","__v":19,"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"},"__v":39,"project":"53fe6dc5addab8973c1af267","user":"53fe70beaddab8973c1af273","parentDoc":null,"updates":["5661c947789d740d00bc5306"],"next":{"pages":[],"description":""},"createdAt":"2015-10-07T01:40:47.679Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":0,"body":"# Adding the Clef button to your site\n\nThe first step to integrating Clef is adding our button to your site. To make this easy, we have a super simple script tag that you can add to your HTML — it'll take care of rendering the button wherever you insert it:\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/redirect\\\" \\n        data-type=\\\"login\\\">\\n</script>\",\n      \"language\": \"html\"\n    }\n  ]\n}\n[/block]\nThis will render a button that looks like:\n[block:html]\n{\n  \"html\": \"<iframe src=\\\"https://clef.io/iframes/button?type=login\\\"\\n        width=\\\"100%\\\" height=\\\"38px\\\" style=\\\"border:none; overflow:hidden;\\\"\\n        />\"\n}\n[/block]\nYou'll want to replace `data-app-id` with the Application ID you receive when you create an integration in our [developer dashboard](https://getclef.com/user/login). \n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"You'll also want to randomly generate a `state` parameter and put it in a cookie and `data-state`. For more info, check out our docs on [verifying the state parameter](http://docs.getclef.com/v1.0/docs/verifying-state-parameter). We have examples for generating `state` in our sample apps for [Python](https://github.com/clef/sample-flask/blob/master/app.py#L82-L85), [Ruby](https://github.com/clef/sample-ruby/blob/master/app.rb#L19-L25), [Node](https://github.com/clef/sample-node/blob/master/app.js#L86-L92) and [PHP](https://github.com/clef/sample-php/blob/master/index.php#L8-L12).\"\n}\n[/block]\nNow that you've put the Clef button on your website, let's do something with it.\n\nAfter a new user clicks the Clef button and sync with their phone, their browser will redirect automatically to your `data-redirect-url` with an OAuth authorization code. When this happens, you'll want to get information about that user from Clef and create a new model for them in your database. \n\n# Getting user information from Clef\n\nWhen a user's browser redirects to your `data-redirect-url`, you'll do Clef's authentication handshake to get information about that user. This happens on your server, and the easiest way to implement the handshake is by using one of our [API Libraries](doc:api-libraries). In this tutorial, we'll show code for **Python**, **Ruby**, **PHP**, and **Node**. \n\nIn your webserver's `data-redirect-url` endpoint, grab the authorization `code` from the GET parameters passed to your server. \n\nYou'll also want to verify that the `state` parameter is the same as the one you used to populate `data-state` when you added the Clef button. \n\nFrom there, it's easy to exchange the code for user information: \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"import clef\\nclef.initialize(app_id=APP_ID, app_secret=APP_SECRET)\\n\\n# In your redirect URL endpoint: \\n\\n# Get the state parameter passed as a query arg and verify it\\nstate = request.args.get('state')\\nassert_state_is_valid(state)\\n\\n# Get the authorization code passed as a query arg\\ncode = request.args.get('code')\\ntry:\\n  user_information = clef.get_login_information(code=code)\\nexcept clef.APIError, e:\\n  # An error occurred while trying to get user information\\n  abort(500)\\n\\n# ...\\n\\ndef assert_state_is_valid(state):\\n  state_is_valid = ('state' in session\\n        and len(session['state']) > 0\\n        and session['state'] == state)\\n  session.pop('state', None)\\n  if not state_is_valid:\\n    abort(403)\",\n      \"language\": \"python\"\n    },\n    {\n      \"code\": \"var clef = require('clef').initialize({\\n    appID: APP_ID,\\n    appSecret: APP_SECRET\\n});\\n\\n// In your redirect URL endpoint: \\n// Get the state parameter passed as a query arg and verify it\\nvar state = req.query.state;\\nassertStateParameterIsValid(req.session, state);\\n\\n// Get the authorization code passed as a query arg\\nvar code = req.query.code;\\nclef.getLoginInformation({code: code}, function(err, userInformation) {\\n    if (err) {\\n        // An error occurred while trying to get user information\\n    } else {\\n        var clefID = userInformation.id;\\n    }\\n});\\n\\n// ...\\n\\nfunction assertStateParameterIsValid(session, state) {\\n    stateIsValid = session.state && session.state.length > 0 && state === session.state;\\n    delete session.state;\\n  \\tif (!stateIsValid) {\\n      throw new Error(\\\"State didn't match\\\");\\n    }\\n};\",\n      \"language\": \"javascript\",\n      \"name\": \"Node\"\n    },\n    {\n      \"code\": \"<?php\\n\\n# In your redirect URL endpoint:\\n\\\\Clef\\\\Clef::initialize(APP_ID, APP_SECRET);\\n\\n// Get the state parameter passed as a query arg and verify it\\nassert_state_is_valid($_GET[\\\"state\\\"]);\\n\\n// Get user information using the authorization code passed as a query arg\\ntry {\\n\\t$response = \\\\Clef\\\\Clef::get_login_information($_GET[\\\"code\\\"]);\\n\\t$user_information = $response->info;\\n} catch (Exception $e) {\\n\\t// An error occurred while trying to get user information\\n\\techo \\\"Login with Clef failed: \\\" . $e->getMessage();\\n}\\n\\n// ... \\n\\nfunction assert_state_is_valid($state) {\\n\\t$is_valid = isset($_SESSION['state']) && strlen($_SESSION['state']) > 0 && $_SESSION['state'] == $state;\\n  unset($_SESSION['state']);\\n  if (!$is_valid) {\\n\\t\\theader('HTTP/1.0 403 Forbidden');\\n\\t\\techo \\\"The state parameter didn't match what was passed in to the Clef button.\\\";\\n\\t\\texit;\\n\\t}\\n\\treturn $is_valid;\\n}\\n\\n?>\",\n      \"language\": \"php\"\n    }\n  ]\n}\n[/block]\n# Registering a new user\n\nNow that you've received the user's information, it's time to register them as a new user in your database and log them in. \n[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"Updating your User model\",\n  \"body\": \"Before you begin, you'll need to add a `clef_id` column to your user table:\\n\\n```\\nALTER TABLE user ADD clef_id bigint(20);\\n```\\n\\nYou'll use `clef_id` to look users up on subsequent logins with Clef.\"\n}\n[/block]\nTo create a new user in your database, you can use information passed by Clef in `user_information`. You can control what information you receive in the Clef developer dashboard, but by default, you'll get `id`, an integer ID that's specific to the user logging in to your site:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"# Grab the information you want\\nclef_id = user_information['id']\\nemail = user_information['email']\\nfirst_name = user_information['first_name']\\n\\n# First, check if a user with that clef_id is already in your database\\nuser = User.query.filter_by(clef_id=clef_id).first()\\nif not user:\\n  # Create a new user with the given info and clef_id\\n\\tuser = User(email=email, first_name=first_name, clef_id=clef_id)\",\n      \"language\": \"python\"\n    },\n    {\n      \"code\": \"var clefID = userInformation['id'];\\nvar email = userInformation['email'];\\n\\n// This example uses the findOrCreate function from the Sequelize ORM (http://docs.sequelizejs.com/en/latest/docs/models-usage/#findorcreate-search-for-a-specific-element-or-create-it-if-not-available).\\nUser.findOrCreate({ \\n  where: { clefID: clefID }, \\n  defaults: { email: email }\\n}).spread(function(user, created) {\\n\\tconsole.log(\\\"Here's a user:\\\" + user);\\n});\\n\",\n      \"language\": \"javascript\",\n      \"name\": \"Node\"\n    },\n    {\n      \"code\": \"<?php\\n\\n// ...\\n\\n// This example uses raw SQL, but the concept is the same with an ORM \\n// like Propel or Doctrine — query by clef_id, and then create a new user\\n// if there isn't already one.\\n$user = get_user_from_clef_id($user_information->id);\\nif (!$user) {\\n\\t$user = insert_user($user_information->id, $user_information->email);\\n}\\n\\n// ...\\n\\nfunction get_user_from_clef_id($clef_id) {\\n    $query = \\\"SELECT * FROM \\\". DB_NAME .\\\".users WHERE clef_id='{$clef_id}'\\\";\\n    if (!$result = $mysql->query($query)) {\\n        die('There was an error running the query: ' . $mysql->error);\\n    }\\n    $user = $result->fetch_assoc();\\n    if (!$user || sizeof($user) == 0) return false;\\n    return $user;\\n}\\n\\nfunction insert_user($clef_id, $email) {\\n    $id = $mysql->escape_string($id);\\n    $name = $mysql->escape_string($name);\\n    $query = \\\"INSERT INTO \\\". DB_NAME .\\\".users (clef_id, name) VALUES ('{$id}', '{$name}');\\\";\\n    if (!$result = $mysql->query($query)) {\\n        die('There was an error running the query: ' . $mysql->error);\\n    }\\n    return $result;\\n}\\n\\n?>\",\n      \"language\": \"php\"\n    }\n  ]\n}\n[/block]\n# Next up\n\nCongrats! You've handled Clef's authentication handshake and added a new user to your database.\n\nNext, you'll want to [log your users in](doc:log-your-users-in).\n[block:html]\n{\n  \"html\": \"<div></div>\\n<a class=\\\"clef-button blue\\\" href=\\\"/v1.0/docs/log-your-users-in\\\">See \\\"Log your users in\\\"</a>\\n<style></style>\"\n}\n[/block]","excerpt":"In this tutorial, you'll learn how to register your users when they sign up through Clef. If you need help after reading this, chat live with our developers in Clef's [community room](http://community.getclef.com).","slug":"register-new-users","type":"basic","title":"Register new users"}

Register new users

In this tutorial, you'll learn how to register your users when they sign up through Clef. If you need help after reading this, chat live with our developers in Clef's [community room](http://community.getclef.com).

# Adding the Clef button to your site The first step to integrating Clef is adding our button to your site. To make this easy, we have a super simple script tag that you can add to your HTML — it'll take care of rendering the button wherever you insert it: [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/redirect\" \n data-type=\"login\">\n</script>", "language": "html" } ] } [/block] This will render a button that looks like: [block:html] { "html": "<iframe src=\"https://clef.io/iframes/button?type=login\"\n width=\"100%\" height=\"38px\" style=\"border:none; overflow:hidden;\"\n />" } [/block] You'll want to replace `data-app-id` with the Application ID you receive when you create an integration in our [developer dashboard](https://getclef.com/user/login). [block:callout] { "type": "info", "body": "You'll also want to randomly generate a `state` parameter and put it in a cookie and `data-state`. For more info, check out our docs on [verifying the state parameter](http://docs.getclef.com/v1.0/docs/verifying-state-parameter). We have examples for generating `state` in our sample apps for [Python](https://github.com/clef/sample-flask/blob/master/app.py#L82-L85), [Ruby](https://github.com/clef/sample-ruby/blob/master/app.rb#L19-L25), [Node](https://github.com/clef/sample-node/blob/master/app.js#L86-L92) and [PHP](https://github.com/clef/sample-php/blob/master/index.php#L8-L12)." } [/block] Now that you've put the Clef button on your website, let's do something with it. After a new user clicks the Clef button and sync with their phone, their browser will redirect automatically to your `data-redirect-url` with an OAuth authorization code. When this happens, you'll want to get information about that user from Clef and create a new model for them in your database. # Getting user information from Clef When a user's browser redirects to your `data-redirect-url`, you'll do Clef's authentication handshake to get information about that user. This happens on your server, and the easiest way to implement the handshake is by using one of our [API Libraries](doc:api-libraries). In this tutorial, we'll show code for **Python**, **Ruby**, **PHP**, and **Node**. In your webserver's `data-redirect-url` endpoint, grab the authorization `code` from the GET parameters passed to your server. You'll also want to verify that the `state` parameter is the same as the one you used to populate `data-state` when you added the Clef button. From there, it's easy to exchange the code for user information: [block:code] { "codes": [ { "code": "import clef\nclef.initialize(app_id=APP_ID, app_secret=APP_SECRET)\n\n# In your redirect URL endpoint: \n\n# Get the state parameter passed as a query arg and verify it\nstate = request.args.get('state')\nassert_state_is_valid(state)\n\n# Get the authorization code passed as a query arg\ncode = request.args.get('code')\ntry:\n user_information = clef.get_login_information(code=code)\nexcept clef.APIError, e:\n # An error occurred while trying to get user information\n abort(500)\n\n# ...\n\ndef assert_state_is_valid(state):\n state_is_valid = ('state' in session\n and len(session['state']) > 0\n and session['state'] == state)\n session.pop('state', None)\n if not state_is_valid:\n abort(403)", "language": "python" }, { "code": "var clef = require('clef').initialize({\n appID: APP_ID,\n appSecret: APP_SECRET\n});\n\n// In your redirect URL endpoint: \n// Get the state parameter passed as a query arg and verify it\nvar state = req.query.state;\nassertStateParameterIsValid(req.session, state);\n\n// Get the authorization code passed as a query arg\nvar code = req.query.code;\nclef.getLoginInformation({code: code}, function(err, userInformation) {\n if (err) {\n // An error occurred while trying to get user information\n } else {\n var clefID = userInformation.id;\n }\n});\n\n// ...\n\nfunction assertStateParameterIsValid(session, state) {\n stateIsValid = session.state && session.state.length > 0 && state === session.state;\n delete session.state;\n \tif (!stateIsValid) {\n throw new Error(\"State didn't match\");\n }\n};", "language": "javascript", "name": "Node" }, { "code": "<?php\n\n# In your redirect URL endpoint:\n\\Clef\\Clef::initialize(APP_ID, APP_SECRET);\n\n// Get the state parameter passed as a query arg and verify it\nassert_state_is_valid($_GET[\"state\"]);\n\n// Get user information using the authorization code passed as a query arg\ntry {\n\t$response = \\Clef\\Clef::get_login_information($_GET[\"code\"]);\n\t$user_information = $response->info;\n} catch (Exception $e) {\n\t// An error occurred while trying to get user information\n\techo \"Login with Clef failed: \" . $e->getMessage();\n}\n\n// ... \n\nfunction assert_state_is_valid($state) {\n\t$is_valid = isset($_SESSION['state']) && strlen($_SESSION['state']) > 0 && $_SESSION['state'] == $state;\n unset($_SESSION['state']);\n if (!$is_valid) {\n\t\theader('HTTP/1.0 403 Forbidden');\n\t\techo \"The state parameter didn't match what was passed in to the Clef button.\";\n\t\texit;\n\t}\n\treturn $is_valid;\n}\n\n?>", "language": "php" } ] } [/block] # Registering a new user Now that you've received the user's information, it's time to register them as a new user in your database and log them in. [block:callout] { "type": "warning", "title": "Updating your User model", "body": "Before you begin, you'll need to add a `clef_id` column to your user table:\n\n```\nALTER TABLE user ADD clef_id bigint(20);\n```\n\nYou'll use `clef_id` to look users up on subsequent logins with Clef." } [/block] To create a new user in your database, you can use information passed by Clef in `user_information`. You can control what information you receive in the Clef developer dashboard, but by default, you'll get `id`, an integer ID that's specific to the user logging in to your site: [block:code] { "codes": [ { "code": "# Grab the information you want\nclef_id = user_information['id']\nemail = user_information['email']\nfirst_name = user_information['first_name']\n\n# First, check if a user with that clef_id is already in your database\nuser = User.query.filter_by(clef_id=clef_id).first()\nif not user:\n # Create a new user with the given info and clef_id\n\tuser = User(email=email, first_name=first_name, clef_id=clef_id)", "language": "python" }, { "code": "var clefID = userInformation['id'];\nvar email = userInformation['email'];\n\n// This example uses the findOrCreate function from the Sequelize ORM (http://docs.sequelizejs.com/en/latest/docs/models-usage/#findorcreate-search-for-a-specific-element-or-create-it-if-not-available).\nUser.findOrCreate({ \n where: { clefID: clefID }, \n defaults: { email: email }\n}).spread(function(user, created) {\n\tconsole.log(\"Here's a user:\" + user);\n});\n", "language": "javascript", "name": "Node" }, { "code": "<?php\n\n// ...\n\n// This example uses raw SQL, but the concept is the same with an ORM \n// like Propel or Doctrine — query by clef_id, and then create a new user\n// if there isn't already one.\n$user = get_user_from_clef_id($user_information->id);\nif (!$user) {\n\t$user = insert_user($user_information->id, $user_information->email);\n}\n\n// ...\n\nfunction get_user_from_clef_id($clef_id) {\n $query = \"SELECT * FROM \". DB_NAME .\".users WHERE clef_id='{$clef_id}'\";\n if (!$result = $mysql->query($query)) {\n die('There was an error running the query: ' . $mysql->error);\n }\n $user = $result->fetch_assoc();\n if (!$user || sizeof($user) == 0) return false;\n return $user;\n}\n\nfunction insert_user($clef_id, $email) {\n $id = $mysql->escape_string($id);\n $name = $mysql->escape_string($name);\n $query = \"INSERT INTO \". DB_NAME .\".users (clef_id, name) VALUES ('{$id}', '{$name}');\";\n if (!$result = $mysql->query($query)) {\n die('There was an error running the query: ' . $mysql->error);\n }\n return $result;\n}\n\n?>", "language": "php" } ] } [/block] # Next up Congrats! You've handled Clef's authentication handshake and added a new user to your database. Next, you'll want to [log your users in](doc:log-your-users-in). [block:html] { "html": "<div></div>\n<a class=\"clef-button blue\" href=\"/v1.0/docs/log-your-users-in\">See \"Log your users in\"</a>\n<style></style>" } [/block]