4.5.3.1. Social Login в REST API
Механизм авторизации через социальные сети, или social login, также можно использовать в REST API. Исходный код приложения, описанного в этом примере, доступен на GitHub, а сам пример описан в разделе Social Login. Ниже приведены ключевые моменты этого примера, позволяющие получить OAuth-токен через аккаунт Facebook.
-
Создайте пакет
restapi
в корневом каталоге модуля web и поместите в него собственный контроллер Spring MVC. Контроллер должен содержать два основных метода:get()
, возвращающийResponseEntity
, иlogin()
, в котором мы будем получать OAuth-токен.@RequestMapping(method = RequestMethod.GET) public ResponseEntity get() { String loginUrl = getAsPrivilegedUser(() -> facebookService.getLoginUrl(getAppUrl(), OAuth2ResponseType.CODE_TOKEN) ); HttpHeaders headers = new HttpHeaders(); headers.set(HttpHeaders.LOCATION, loginUrl); return new ResponseEntity<>(headers, HttpStatus.FOUND); }
Здесь мы проверяем переданный код Facebook, получаем код доступа и издаём токен с помощью
OAuthTokenIssuer
:@RequestMapping(method = RequestMethod.POST, value = "login") public ResponseEntity<OAuth2AccessToken> login(@RequestParam("code") String code) { User user = getAsPrivilegedUser(() -> { FacebookUserData userData = facebookService.getUserData(getAppUrl(), code); return socialRegistrationService.findOrRegisterUser( userData.getId(), userData.getEmail(), userData.getName()); }); OAuth2AccessTokenResult tokenResult = oAuthTokenIssuer.issueToken(user.getLogin(), messageTools.getDefaultLocale(), Collections.emptyMap()); HttpHeaders headers = new HttpHeaders(); headers.set(HttpHeaders.CACHE_CONTROL, "no-store"); headers.set(HttpHeaders.PRAGMA, "no-cache"); return new ResponseEntity<>(tokenResult.getAccessToken(), headers, HttpStatus.OK); }
-
Исключите пакет
restapi
из сканирования в модулях web/core: это необходимо, так как бинOAuthTokenIssuer
доступен только внутри контекста REST API, и сканирование его в контексте приложения будет вызывать ошибку.<context:component-scan base-package="com.company.demo"> <context:exclude-filter type="regex" expression="com\.company\.demo\.restapi\..*"/> </context:component-scan>
-
Создайте файл
facebook-login-demo.html
в каталоге проектаmodules/web/web/VAADIN
. Он будет содержать JavaScript-код, выполняющийся на HTML-странице:<html> <head> <title>Facebook login demo with REST-API</title> <script src="jquery-3.2.1.min.js"></script> <style type="text/css"> #users { display: none; } </style> </head> <body> <h1>Facebook login demo with REST-API</h1> <script type="application/javascript"...> </script> <a id="fbLink" href="/app/rest/facebook">Login with Facebook</a> <div id="users"> You are logged in! <h1>Users</h1> <div id="usersList"> </div> </div> </body> </html>
В этом скрипте мы попробуем залогиниться через Facebook. Сначала удаляем лишний код из URL, затем передаём код в REST API для получения OAuth-токена, и в случае успешной аутентификации мы сможем загружать и сохранять данные как обычно:
var oauth2Token = null; function tryToLoginWithFacebook() { var urlHash = window.location.hash; if (urlHash && urlHash.indexOf('&code=') >= 0) { console.log("Try to login to CUBA REST-API!"); var urlCode = urlHash.substring(urlHash.indexOf('&code=') + '&code='.length); console.log("Facebook code: " + urlCode); history.pushState("", document.title, window.location.pathname); $.post({ url: '/app/rest/facebook/login', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, dataType: 'json', data: {code: urlCode}, success: function (data) { oauth2Token = data.access_token; loadUsers(); } }) } } function loadUsers() { $.get({ url: '/app/rest/v2/entities/sec$User?view=_local', headers: { 'Authorization': 'Bearer ' + oauth2Token, 'Content-Type': 'application/x-www-form-urlencoded' }, success: function (data) { $('#fbLink').hide(); $('#users').show(); $.each(data, function (i, user) { $('#usersList').append("<li>" + user.name + " (" + user.email + ")</li>"); }); } }); } tryToLoginWithFacebook();
Другой пример использования JavaScript-кода в приложениях CUBA вы можете найти в разделе Пример использования из JavaScript.