]> juplo.de Git - website/blob
1abe8229facbc49fffebcbbb83c882107da8b0f1
[website] /
1 ---
2 _edit_last: "2"
3 categories:
4   - howto
5 date: "2016-01-26T16:05:28+00:00"
6 guid: http://juplo.de/?p=671
7 parent_post_id: null
8 post_id: "671"
9 tags:
10   - createmedia.nrw
11   - facebook
12   - graph-api
13   - java
14   - oauth2
15   - spring
16   - spring-boot
17   - spring-social
18 title: 'Develop a Facebook-App with Spring-Social – Part VI: Sign In Users Through The Canvas-Page'
19 url: /develop-a-facebook-app-with-spring-social-part-06-sign-in-users-through-the-canvas-page/
20
21 ---
22 In this series of Mini-How-Tow's I will describe how to develop a facebook app with the help of [Spring-Social](http://projects.spring.io/spring-social/ "Learn more about Spring-Social")
23
24 In [the last part of this series](/develop-a-facebook-app-with-spring-social-part-05-refactor-the-redirect-logic/ "Read part 5 of this series"), we refactored our authentication-concept, so that it can be replaced by Spring Security later on more easy.
25
26 In this part, we will turn our app into a real Facebook-App, that is rendered inside Facebook and signs in users through the `signed_request`.
27
28 ## The Source is With You
29
30 You can find the source-code on [/git/examples/facebook-app/](/git/examples/facebook-app/ "Link for cloning")
31 and [browse it via gitweb](/gitweb/?p=examples/facebook-app;a=summary "Browse the source-code now").
32 Check out `part-06` to get the source for this part of the series.
33
34 ## What The \*\#&! Is a `signed_request`
35
36 If you add the platform **Facebook Canvas** to your app, you can present your app inside of Facebook.
37 It will be accessible on a URL like **`https://apps.facebook.com/YOUR_NAMESPACE`** then and if a (known!) user accesses this URL, facebook will send a [`signed_request`](https://developers.facebook.com/docs/reference/login/signed-request "Read more about the fields, that are contained in the signed_request"), that already contains some data of this user an an authorization to retrieve more.
38
39 ## Sign In Users With `signed_request` In 5 Simple Steps
40
41 As I first tried to extend the [simple example](http://spring.io/guides/gs/accessing-facebook/ "Read the original guide, this article-series is based on"), this article-series is based on, I stumbled across multiple misunderstandings.
42 But now, as I guided you around all that obstacles, it is fairly easy to refine our app, so that is can sign in users through the signed\_request, send to a Canvas-Page.
43
44 You just have to:
45
46 1. Add the platform "Facebook Canvas" in the settings of your app and choose a canvas-URL.
47 1. Reconfigure your app to support HTTPS, because Facebook requires the canvas-URL to be secured by SSL.
48 1. Configure the `CanvasSignInController`.
49 1. Allow the URL of the canvas-page to be accessed unauthenticated.
50 1. Enable Sign-Up throw your canvas-page.
51
52 That is all, there is to do.
53 But now, step by step...
54
55 ## Step 1: Turn Your App Into A Canvas-Page
56
57 Go to the settings-panel of your app on [https://developers.facebook.com/apps](https://developers.facebook.com/apps "Log in to your developer-account on Facebook now") and click on _Add Platform_.
58 Choose _Facebook Canvas_.
59 Pick a secure URL, where your app will serve the canvas-page.
60
61 For example: `https://localhost:8443`.
62
63 Be aware, that the URL has to be publicly available, if you want to enable other users to access your app.
64 But that also counts for the Website-URL `http://localhost:8080`, that we are using already.
65
66 Just remember, if other people should be able to access your app later, you have to change these URL's to something, they can access, because all the content of your app is served by you, not by Facebook.
67 A Canvas-App just embedds your content in an iFrame inside of Facebook.
68
69 ## Step 2: Reconfigure Your App To Support HTTPS
70
71 Add the following lines to your `src/main/resources/application.properties`:
72
73 ```properties
74 server.port: 8443
75 server.ssl.key-store: keystore
76 server.ssl.key-store-password: secret
77
78 ```
79
80 I have included a self-signed `keystore` with the password `secret` in the source, that you can use for development and testing.
81 But of course, later, you have to create your own keystore with a certificate that is signed by an official certificate authority, that is known by the browsers of your users.
82
83 Since your app now listens on `8443` an uses `HTTPS`, you have to change the URL, that is used for the platform "Website", if you want your sign-in-page to continue to work in parallel to the sign-in through the canvas-page.
84
85 For now, you can simply change it to `https://locahost:8443/` in the settings-panel of your app.
86
87 ## Step 3: Configure the `CanvasSignInController`
88
89 To actually enable the [automatic handling](https://developers.facebook.com/docs/games/gamesonfacebook/login#usingsignedrequest "Read about all the cumbersome steps, that would be necesarry, if you had to handle a signed_requst by yourself") of the `signed_request`, that is, decoding the `signed_request` and sign in the user with the data provided in the `signed_request`, you just have to add the `CanvasSignInController` as a bean in your `SocialConfig`:
90
91 ```Java
92 @Bean
93 public CanvasSignInController canvasSignInController(
94     ConnectionFactoryLocator connectionFactoryLocator,
95     UsersConnectionRepository usersConnectionRepository,
96     Environment env
97     )
98 {
99   return
100       new CanvasSignInController(
101           connectionFactoryLocator,
102           usersConnectionRepository,
103           new UserCookieSignInAdapter(),
104           env.getProperty("facebook.app.id"),
105           env.getProperty("facebook.app.secret"),
106           env.getProperty("facebook.app.canvas")
107           );
108 }
109
110 ```
111
112 ## Step 4: Allow the URL Of Your Canvas-Page To Be Accessed Unauthenticated
113
114 Since [we have "secured" all of our pages](/develop-a-facebook-app-with-spring-social-part-05-refactor-the-redirect-logic "Read more about the refactoring, that ensures, that every request, that is made to our app, is authenticated") except of our sign-in-page `/signin*`, so that they can only be accessed by an authenticated user, we have to explicitly allow unauthenticated access to our new special sign-in-page.
115
116 To achieve that, we have to refine our [`UserCookieInterceptor`](/develop-a-facebook-app-with-spring-social-part-05-refactor-the-redirect-logic#redirect "Compare the changes to the unchanged method of our UserCookieInterceptor") as follows.
117 First add a pattern for all pages, that are allowed to be accessed unauthenticated:
118
119 ```Java
120 private final static Pattern PATTERN = Pattern.compile("^/signin|canvas");
121
122 ```
123
124 Then match the requests against this pattern, instead of the fixed string `/signin`:
125
126 ```Java
127 if (PATTERN.matcher(request.getServletPath()).find())
128   return true;
129
130 ```
131
132 ## Step 5: Enable Sign-Up Through Your Canvas-Page
133
134 Facebook always sends a `signed_request` to your app, if a user visits your app through the canvas-page.
135 But on the first visit of a user, the `signed_request` does not authenticate the user.
136 In this case, the only data that is presented to your page is the language and locale of the user and his or her age.
137
138 Because the data, that is needed to sign in the user, is missing, the `CanvasSignInController` will issue an explicit authentication-request to the Graph-API via a so called [Server-Side Log-In](https://developers.facebook.com/docs/games/gamesonfacebook/login#serversidelogin "Read more details about the process of a Server-Side Log-In on Facebook").
139 This process includes a redirect to the Login-Dialog of Facebook and then a second redirect back to your app.
140 It requires the specification of a full absolute URL to redirect back to.
141
142 Since we are configuring the canvas-login-in, we want, that new users are redirected to the canvas-page of our app.
143 Hence, you should use the Facebook-URL of your app: `https://apps.facebook.com/YOUR_NAMESPACE`.
144 This will result in a call to your canvas-page with a `signed_request`, that authenticates the new user, if the user accepts to share the requested data with your app.
145
146 Any other page of your app would work as well, but the result would be a call to the stand-alone version of your app (the version of your app that is called the "Website"-platform of your app by Facebook), meaning, that your app is not rendered inside of Facebook.
147 Also it requires one more call of your app to the Graph-API to actually sign-in the new user, because Facebook sends the `signed_request` only the canvas-page of your app.
148
149 To specify the URL I have introduced a new attribute `facebook.app.canvas` that is handed to the `CanvasSignInController`.
150 You can specifiy it, when starting your app:
151
152 ```bash
153 mvn spring-boot:run \
154     -Dfacebook.app.id=YOUR_ID \
155     -Dfacebook.app.secret=YOUR_SECRET \
156     -Dfacebook.app.canvas=https://apps.facebook.com/YOUR_NAMESPACE
157
158 ```
159
160 Be aware, that this process requires the automatic sign-up of new users, that we enabled in [part 3](/develop-a-facebook-app-with-spring-social-part-03-implementing-a-user-id-source#plumbing-UserIdSource "Jump back to part 3 of this series to reread, how we enabled the automatic sign-up") of this series.
161 Otherwise, the user would be redirected to the sign-up-page of your application, after he allowed your app to access the requested data.
162 Obviously, that would be very confusing for the user, so we really nead automati sign-up in this use-case!
163
164 ## Coming Next...
165
166 In [the next part](/develop-a-facebook-app-with-spring-social-part-07-what-is-going-on-on-the-wire/ "Jump to the next part of this series and learn how to turn on debugging for the HTTP-communication between your app and the Graph-API") of this series, I will show you, how you can debug the calls, that Spring Social makes to the Graph-API, by turning on the debugging of the classes, that process the HTTP-requests and -responses, that your app is making.