{"_id":"53fe732eaddab8973c1af27f","tags":[],"comments":[],"is_link":false,"category":{"_id":"53fe7d8daddab8973c1af2b1","project":"53fe6dc5addab8973c1af267","__v":5,"version":"53fe6dc5addab8973c1af26a","pages":["53fe732eaddab8973c1af27f","53fe7df4addab8973c1af2b7","53fe7e08addab8973c1af2b9","544945633acc37080099e719","551c450c0360770d00f5ce3a"],"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2014-08-28T00:53:33.662Z","from_sync":false,"order":5,"slug":"login-reference","title":"Login Reference"},"user":"53fe70beaddab8973c1af273","__v":27,"parentDoc":null,"project":"53fe6dc5addab8973c1af267","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"},"updates":[],"next":{"pages":[],"description":""},"createdAt":"2014-08-28T00:09:18.156Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","try":true,"auth":"never","params":[],"url":""},"isReference":false,"order":0,"body":"When a user clicks the Clef button and syncs the Clef wave, they'll be redirected to your **redirect URL**.  There, you need to implement a standard [OAuth 2.0 handshake](http://oauth.net/2/). \n\n# Exchanging the OAuth code\n\nWhen the user is redirected, an [OAuth authorization code](http://tools.ietf.org/html/rfc6749#section-1.3.1) will be passed as URL parameter named `code`. You use our API to exchange that code for an **access token**.\n\nThe sample code below shows how to exchange a Clef OAuth authorization code for an access token. \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"require 'httparty'\\nrequire 'json'\\n\\nAPP_ID = '6f8fb6e642924a5e9e7deacf35292abf'\\nAPP_SECRET = '27788a6c0934331258651af709813ba2'\\n\\ncode = params[:code]\\nstate = params[:state]\\n\\nassert_state_is_valid(state)\\n\\ndata = {\\n    body: {\\n        code: code,\\n        app_id: APP_ID,\\n        app_secret: APP_SECRET\\n    }\\n}\\n\\nurl = \\\"https://clef.io/api/v1/authorize\\\"\\n\\nresponse = HTTParty.post(url, data)\\n\\nif response['success']\\n    access_token = response['access_token']\\nelse\\n    p response['error']\\nend\",\n      \"language\": \"ruby\",\n      \"name\": null\n    },\n    {\n      \"code\": \"import requests\\nimport json\\n\\nAPP_ID = '8c9253dca23777745c9102e0be99ea70'\\nAPP_SECRET = 'a9a356f16c77bdcddf15f0a1c407dd3a'\\n\\ncode = request.args.get('code')\\nstate = request.args.get('state')\\n\\nassert_state_is_valid(state)\\n\\ndata = {\\n    'app_id': APP_ID,\\n    'app_secret': APP_SECRET,\\n    'code': code\\n}\\n\\nurl = 'https://clef.io/api/v1/authorize'\\n\\nresponse = requests.post(url, data=data)\\njson_response = json.loads(response.text)\\n\\nif json_response.get('success', False):\\n    access_token = json_response['access_token']\\nelse:\\n    print json_response['error']\\n                            \",\n      \"language\": \"python\"\n    },\n    {\n      \"code\": \"<?php\\n\\n$app_id = '562306be5c59cc3f2da25095c05da670';\\n$app_secret = '9fd4e0d1e240e6f95b20a6223c3edbfc';\\n\\n$code = $_GET[\\\"code\\\"];\\n$state = $_GET[\\\"state\\\"];\\n\\nassert_state_is_valid($state);\\n\\n$postdata = http_build_query(\\n    array(\\n        'code' => $code,\\n        'app_id' => $app_id,\\n        'app_secret' => $app_secret\\n    )\\n);\\n\\n$opts = array('http' =>\\n    array(\\n        'method'  => 'POST',\\n        'header'  => 'Content-type: application/x-www-form-urlencoded',\\n        'content' => $postdata\\n    )\\n);\\n\\n$url = 'https://clef.io/api/v1/authorize';\\n\\n$context  = stream_context_create($opts);\\n$response = file_get_contents($url, false, $context);\\n$response = json_decode($response, true);\\n\\nif ($response && $response['success']) {\\n    $access_token = $response['access_token'];\\n} else {\\n    echo $response['error'];\\n}\\n?>\",\n      \"language\": \"php\"\n    }\n  ]\n}\n[/block]\n# Verifying the `state` parameter\n\nTo protect against CSRF attacks, you should *always* pass in a `state` parameter to either the Clef button (with `data-state`) or the Clef login URL (by specifying `&state=` in the URL). In the handshake, this `state` parameter will be passed back and you'll need to verify that it is the same as the one you passed in.\n\n**This check is especially important if you are connecting Clef to an already existing account. If it's not implemented correctly, it can lead to [\"The Most Common OAuth2 Vulnerability\"](http://homakov.blogspot.com/2012/07/saferweb-most-common-oauth2.html).**\n\nYou can read more about how to do this [here](doc:verifying-state-parameter).\n\n# Next up\n\nOnce you've exchanged your OAuth code for an access token, you'll want to [get user information](/v1.0/docs/accessing-user-information) so you can look the user up in your database. \n[block:html]\n{\n  \"html\": \"<div></div>\\n<a class=\\\"clef-button blue\\\" href=\\\"/v1.0/docs/accessing-user-information\\\">Go to the next section</a>\\n<style></style>\"\n}\n[/block]","excerpt":"Completing the Clef OAuth handshake is easy.","slug":"authenticating-users","type":"basic","title":"Completing the OAuth handshake"}

Completing the OAuth handshake

Completing the Clef OAuth handshake is easy.

When a user clicks the Clef button and syncs the Clef wave, they'll be redirected to your **redirect URL**. There, you need to implement a standard [OAuth 2.0 handshake](http://oauth.net/2/). # Exchanging the OAuth code When the user is redirected, an [OAuth authorization code](http://tools.ietf.org/html/rfc6749#section-1.3.1) will be passed as URL parameter named `code`. You use our API to exchange that code for an **access token**. The sample code below shows how to exchange a Clef OAuth authorization code for an access token. [block:code] { "codes": [ { "code": "require 'httparty'\nrequire 'json'\n\nAPP_ID = '6f8fb6e642924a5e9e7deacf35292abf'\nAPP_SECRET = '27788a6c0934331258651af709813ba2'\n\ncode = params[:code]\nstate = params[:state]\n\nassert_state_is_valid(state)\n\ndata = {\n body: {\n code: code,\n app_id: APP_ID,\n app_secret: APP_SECRET\n }\n}\n\nurl = \"https://clef.io/api/v1/authorize\"\n\nresponse = HTTParty.post(url, data)\n\nif response['success']\n access_token = response['access_token']\nelse\n p response['error']\nend", "language": "ruby", "name": null }, { "code": "import requests\nimport json\n\nAPP_ID = '8c9253dca23777745c9102e0be99ea70'\nAPP_SECRET = 'a9a356f16c77bdcddf15f0a1c407dd3a'\n\ncode = request.args.get('code')\nstate = request.args.get('state')\n\nassert_state_is_valid(state)\n\ndata = {\n 'app_id': APP_ID,\n 'app_secret': APP_SECRET,\n 'code': code\n}\n\nurl = 'https://clef.io/api/v1/authorize'\n\nresponse = requests.post(url, data=data)\njson_response = json.loads(response.text)\n\nif json_response.get('success', False):\n access_token = json_response['access_token']\nelse:\n print json_response['error']\n ", "language": "python" }, { "code": "<?php\n\n$app_id = '562306be5c59cc3f2da25095c05da670';\n$app_secret = '9fd4e0d1e240e6f95b20a6223c3edbfc';\n\n$code = $_GET[\"code\"];\n$state = $_GET[\"state\"];\n\nassert_state_is_valid($state);\n\n$postdata = http_build_query(\n array(\n 'code' => $code,\n 'app_id' => $app_id,\n 'app_secret' => $app_secret\n )\n);\n\n$opts = array('http' =>\n array(\n 'method' => 'POST',\n 'header' => 'Content-type: application/x-www-form-urlencoded',\n 'content' => $postdata\n )\n);\n\n$url = 'https://clef.io/api/v1/authorize';\n\n$context = stream_context_create($opts);\n$response = file_get_contents($url, false, $context);\n$response = json_decode($response, true);\n\nif ($response && $response['success']) {\n $access_token = $response['access_token'];\n} else {\n echo $response['error'];\n}\n?>", "language": "php" } ] } [/block] # Verifying the `state` parameter To protect against CSRF attacks, you should *always* pass in a `state` parameter to either the Clef button (with `data-state`) or the Clef login URL (by specifying `&state=` in the URL). In the handshake, this `state` parameter will be passed back and you'll need to verify that it is the same as the one you passed in. **This check is especially important if you are connecting Clef to an already existing account. If it's not implemented correctly, it can lead to ["The Most Common OAuth2 Vulnerability"](http://homakov.blogspot.com/2012/07/saferweb-most-common-oauth2.html).** You can read more about how to do this [here](doc:verifying-state-parameter). # Next up Once you've exchanged your OAuth code for an access token, you'll want to [get user information](/v1.0/docs/accessing-user-information) so you can look the user up in your database. [block:html] { "html": "<div></div>\n<a class=\"clef-button blue\" href=\"/v1.0/docs/accessing-user-information\">Go to the next section</a>\n<style></style>" } [/block]