Like Google, the Facebook documentation on login includes two options: using Facebook Javascript SDK and without it. I used the second option, manually building a login flow, to create a Javascript-free login flow for the back-end.
In my simple web application the flow is as follows:
-
When the login button is click, the user is redirected to the facebook page. The login button is inside an anchor tag:
<a href="https://www.facebook.com/v2.12/dialog/oauth?client_id=407938939637716&redirect_uri=http://localhost:8080/test/facebook&scope=email&response_type=code&state=http://localhost:8080/test/|1462070876 ">
The url contains the following parameters:
- client_id from the app's dashboard.
- redirect_uri will receive the response from the Facebook login. The uri must be whitelisted in the App Dashboard.
- state maintains state between the request and callback. It will be appended unchanged to the redirect_uri.
- response_type:
- code - the response data is included as URL parameters and contains code parameter. The data is accessible to the back-end.
- token - the response data is included as a URL fragment and contains an access token. The response hash can be accesses only on the client by javascript.
- scope - a list of Permissions to request from the person using your app. Note, even if you request the email permission it is not guaranteed you will get an email address. For example, if someone signed up for Facebook with a phone number instead of an email address, the email field may be empty.
After a login attempt, the browser is redirected to the redirect_uri with appended response paremeters code and state:
http://localhost:8080/test/facebook?code=AQAlQPnW9Vbft-F8DW_ybmgjnk5fJ9ok7YiOglNDvougkpDUYyOC4D5gdhWQ4o54cYcVE9bihhvKjO6HRIQCXNIhLW6jUlaCvehwScSXbE9U3zDKBsbJo-uvMgPc9xJbzKAunmIdr3dDjJ72-SKqipvEYTkHtKksbVDEfbUR4DRL6ei8SQyf7A-8ULAGhZhJAgLsqfKYkqal2GzgbxtK3npvBS1OiWZFZvlGirHPbnOpM80EO5E7WDBqG7GsSR9c6lM6Xudehpo7U9OacW5h2XDwIuVTCFg3pNgtiptkotEimhBgigdgWTLFJJgYzFhYRrfj3O-ksbcAknd_nqUvYFfgewJo-5ejJ4HL1fGdzlrF-A&state=http%3A%2F%2Flocalhost%3A8080%2Ftest%2F%7C1462070876
The state values in the original request and the response are the same. The code has to be included in a GET request to another endpoint. Additionally, client_id, redirect_uri used in the initial request, and client_secret from the App Dashboard are required.
https://graph.facebook.com/v2.12/oauth/access_token?code=AQAlQPnW9Vbft-F8DW_ybmgjnk5fJ9ok7YiOglNDvougkpDUYyOC4D5gdhWQ4o54cYcVE9bihhvKjO6HRIQCXNIhLW6jUlaCvehwScSXbE9U3zDKBsbJo-uvMgPc9xJbzKAunmIdr3dDjJ72-SKqipvEYTkHtKksbVDEfbUR4DRL6ei8SQyf7A-8ULAGhZhJAgLsqfKYkqal2GzgbxtK3npvBS1OiWZFZvlGirHPbnOpM80EO5E7WDBqG7GsSR9c6lM6Xudehpo7U9OacW5h2XDwIuVTCFg3pNgtiptkotEimhBgigdgWTLFJJgYzFhYRrfj3O-ksbcAknd_nqUvYFfgewJo-5ejJ4HL1fGdzlrF-A&client_id=407938939637716&client_secret=7fd6fa037e097fcf002fb350b815f5b3&redirect_uri=http://localhost:8080/test/facebook
The response is a Json containing an access_token.
{"access_token":"EAAFzBKZBWT9QBABhRNBOKwQZBMza2siRzUZBeQHi0Jp2qrXijTEnbVijy4ZAjnTzBzigZA11Vh4RhZBZB2DDu1n8fEJBdBh5mxFETqJJFLLHQnkG0XyffthKg2tU62csiCvsCHxiVOMuZAWy2lS74sKLTbL8sC8EgLEZD","token_type":"bearer","expires_in":5181583}
That the difference from Google sign in. In Google additionally id_token with the user's detail is received. In Facebook an additional request is required.
Using the received access token, the sever-side code makes yet another GET request retrieves a user email from the Graph API. The /me node is a special endpoint that translates to the user_id of the person whose access token is currently being used to make the API calls. Access tokens are portable. Graph API calls can be made from clients or from your server on behalf of clients. The calls to the Graph API are better secured by adding appsecret_proof parameter.
https://graph.facebook.com/v2.12/me?access_token=EAAFzBKZBWT9QBABhRNBOKwQZBMza2siRzUZBeQHi0Jp2qrXijTEnbVijy4ZAjnTzBzigZA11Vh4RhZBZB2DDu1n8fEJBdBh5mxFETqJJFLLHQnkG0XyffthKg2tU62csiCvsCHxiVOMuZAWy2lS74sKLTbL8sC8EgLEZD&debug=all&fields=email&format=json&method=get&pretty=0&appsecret_proof=34b9499185c81a1f37a68cb3b012ae2dcb6882d8066dc58c88641247c28bbce9
The response is a json:
{"email":"dummy000@mail.ru","id":"10215579219697013","__debug__":{}}
The retrieved email is used to log the user into the web application.
In App Dashboard I used such security settings:
The option below allows only the API calls that either include appsecret_proof or are made from the same device the token was issued.
No comments:
Post a Comment