]> juplo.de Git - website/blob
f7383be2be6f03d8ec530ff390766a3a4b9c2dfd
[website] /
1 ---
2 _edit_last: "2"
3 author: kai
4 categories:
5   - howto
6 date: "2016-01-26T16:05:28+00:00"
7 guid: http://juplo.de/?p=671
8 parent_post_id: null
9 post_id: "671"
10 tags:
11   - createmedia.nrw
12   - facebook
13   - graph-api
14   - java
15   - oauth2
16   - spring
17   - spring-boot
18   - spring-social
19 title: 'Develop a Facebook-App with Spring-Social – Part VI: Sign In Users Through The Canvas-Page'
20 url: /develop-a-facebook-app-with-spring-social-part-06-sign-in-users-through-the-canvas-page/
21
22 ---
23 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")
24
25 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.
26
27 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`.
28
29 ## The Source is With You
30
31 You can find the source-code on [/git/examples/facebook-app/](/git/examples/facebook-app/ "Link for cloning")
32 and [browse it via gitweb](/gitweb/?p=examples/facebook-app;a=summary "Browse the source-code now").
33 Check out `part-06` to get the source for this part of the series.
34
35 ## What The \*\#&! Is a `signed_request`
36
37 If you add the platform **Facebook Canvas** to your app, you can present your app inside of Facebook.
38 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.
39
40 ## Sign In Users With `signed_request` In 5 Simple Steps
41
42 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.
43 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.
44
45 You just have to:
46
47 1. Add the platform "Facebook Canvas" in the settings of your app and choose a canvas-URL.
48 1. Reconfigure your app to support HTTPS, because Facebook requires the canvas-URL to be secured by SSL.
49 1. Configure the `CanvasSignInController`.
50 1. Allow the URL of the canvas-page to be accessed unauthenticated.
51 1. Enable Sign-Up throw your canvas-page.
52
53 That is all, there is to do.
54 But now, step by step...
55
56 ## Step 1: Turn Your App Into A Canvas-Page
57
58 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_.
59 Choose _Facebook Canvas_.
60 Pick a secure URL, where your app will serve the canvas-page.
61
62 For example: `https://localhost:8443`.
63
64 Be aware, that the URL has to be publicly available, if you want to enable other users to access your app.
65 But that also counts for the Website-URL `http://localhost:8080`, that we are using already.
66
67 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.
68 A Canvas-App just embedds your content in an iFrame inside of Facebook.
69
70 ## Step 2: Reconfigure Your App To Support HTTPS
71
72 Add the following lines to your `src/main/resources/application.properties`:
73
74 ```properties
75 server.port: 8443
76 server.ssl.key-store: keystore
77 server.ssl.key-store-password: secret
78
79 ```
80
81 I have included a self-signed `keystore` with the password `secret` in the source, that you can use for development and testing.
82 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.
83
84 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.
85
86 For now, you can simply change it to `https://locahost:8443/` in the settings-panel of your app.
87
88 ## Step 3: Configure the `CanvasSignInController`
89
90 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`:
91
92 ```Java
93 @Bean
94 public CanvasSignInController canvasSignInController(
95     ConnectionFactoryLocator connectionFactoryLocator,
96     UsersConnectionRepository usersConnectionRepository,
97     Environment env
98     )
99 {
100   return
101       new CanvasSignInController(
102           connectionFactoryLocator,
103           usersConnectionRepository,
104           new UserCookieSignInAdapter(),
105           env.getProperty("facebook.app.id"),
106           env.getProperty("facebook.app.secret"),
107           env.getProperty("facebook.app.canvas")
108           );
109 }
110
111 ```
112
113 ## Step 4: Allow the URL Of Your Canvas-Page To Be Accessed Unauthenticated
114
115 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.
116
117 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.
118 First add a pattern for all pages, that are allowed to be accessed unauthenticated:
119
120 ```Java
121 private final static Pattern PATTERN = Pattern.compile("^/signin|canvas");
122
123 ```
124
125 Then match the requests against this pattern, instead of the fixed string `/signin`:
126
127 ```Java
128 if (PATTERN.matcher(request.getServletPath()).find())
129   return true;
130
131 ```
132
133 ## Step 5: Enable Sign-Up Through Your Canvas-Page
134
135 Facebook always sends a `signed_request` to your app, if a user visits your app through the canvas-page.
136 But on the first visit of a user, the `signed_request` does not authenticate the user.
137 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.
138
139 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").
140 This process includes a redirect to the Login-Dialog of Facebook and then a second redirect back to your app.
141 It requires the specification of a full absolute URL to redirect back to.
142
143 Since we are configuring the canvas-login-in, we want, that new users are redirected to the canvas-page of our app.
144 Hence, you should use the Facebook-URL of your app: `https://apps.facebook.com/YOUR_NAMESPACE`.
145 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.
146
147 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.
148 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.
149
150 To specify the URL I have introduced a new attribute `facebook.app.canvas` that is handed to the `CanvasSignInController`.
151 You can specifiy it, when starting your app:
152
153 ```bash
154 mvn spring-boot:run \
155     -Dfacebook.app.id=YOUR_ID \
156     -Dfacebook.app.secret=YOUR_SECRET \
157     -Dfacebook.app.canvas=https://apps.facebook.com/YOUR_NAMESPACE
158
159 ```
160
161 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.
162 Otherwise, the user would be redirected to the sign-up-page of your application, after he allowed your app to access the requested data.
163 Obviously, that would be very confusing for the user, so we really nead automati sign-up in this use-case!
164
165 ## Coming Next...
166
167 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.