2013-12-16 3 views
2

Ситуация в том, что у меня есть макет application.gsp, который определяет макет для всех страниц, кроме страницы входа. Внутри макета находится заголовок, который должен отображать имя текущего зарегистрированного пользователя (плагин Spring Security). Проблема в том, что если пользователь просто регистрирует или использует oAuth в первый раз (то же самое, что и при регистрации), то при входе в систему он увидит и пустёт пятно вместо имени пользователя, потому что макет был отображен до. Если он снова войдет/войдет в систему, он, конечно, увидит его имя пользователя.Графический макет обновления/рендера во время выполнения

P.S. Перемещение заголовка вне макета не является опцией, потому что это приведет к массивному дублированию кода.

Есть ли способ обойти это?

+0

Вы используете плагин Spring Security Core? –

+0

Вы сказали, что перемещение заголовка вне макета не является вариантом, но можно ли использовать ag: включить только для отображения зарегистрированного пользователя, который мог бы попасть в контроллер, чтобы получить имя входа, если оно существует, и сделать Это? – bschipp

+0

Невозможно переслать пользователя из действия аутентификации, например.действие домашней страницы после того, как они вошли в систему? Тогда имя пользователя будет доступно при визуализации представления. – Armand

ответ

1

Я отвечу на свой вопрос для будущих поколений пытается решить ту же проблему.
Уловка заключается в использовании шаблона дизайна декоратора и плохо документированного g: pageProperty gsp tag.

просмотров/макеты/application.gsp:

.... 
<li class="dropdown menu"> 
         <a href="#" class="dropdown-toggle" 
          data-toggle="dropdown"><g:pageProperty name="page.username"/></a> 
         <ul class="dropdown-menu"> 
          <li>Preferences</li> 
          <li> 
           <a href="${resource(file: 'j_spring_security_logout')}" 
            class="navbar-btn btn-danger btn">Logout</a></li> 
         </ul> 
        </li> 
.... 

просмотров/index.gsp:

.... 
<body> 
    <content tag="username"> 
     <g:username username="${username}"/> 
    </content> 
.... 

TagLib/UsernameTagLib.groovy:

class UsernameTagLib { 
def springSecurityService 

/** 
* Check if the username is already available, else inject newly created username into the layout 
* 
* @attr username REQUIRED that was received from the newly registered user 
*/ 
def username = { attrs -> 
    String currentUsername = springSecurityService.getCurrentUser()?.username 
    if (currentUsername) { 
     out << currentUsername 
    } else { 
     out << attrs.username 
    } 
    } 
} 

Созданное имя пользователя передается в views/index.gsp, когда пользователь завершил весь процесс oAuth.

Контроллеры/OauthCallBackController.groovy

.... 
    def facebook() { 
     Token facebookAccessToken = (Token) session[oauthService.findSessionKeyForAccessToken('facebook')] 
     if (facebookAccessToken) { 
      String username = oauthCallBackService.facebook(facebookAccessToken) 
      render view: '/index', model: [username: username] 
     } else failure() 
    } 
.... 

В основном имя пользователя путешествует вверх, пока он не достигнет раскладку, что позволяет мне использовать имя пользователя в заголовке макета и распространение информации о его на всех страницах, которые нуждаются в раскладка.

+0

Вам нужно было добавить одинаковые теги к каждому gsp, который использует этот макет? –

+0

@EdJ, к сожалению, это было так давно, что я больше не помню, не использовал Grails с тех пор – maryokhin

0

Если вы используете Spring Security Core plugin, вы можете ввести reauthenticate в свой контроллер.

springSecurityService.reauthenticate user.username 
+0

Вот как я аутентифицирую пользователей, но это не имеет отношения к проблеме рендеринга макета до того, как пользователь будет аутентифицирован. – maryokhin

0

Вы можете проверить это с SecurityTagLib помощника Spring Security Core.

В вашем application.gsp вы можете иметь:

... 
<sec:ifLoggedIn> 

<!-- Display user field with sec:loggedInUserInfo tag --> 
Welcome Back <sec:loggedInUserInfo field="fullName"/> 

<!-- Check if user have all specified privileges --> 
<sec:ifAllGranted roles="ROLE_ADMIN,ROLE_SUPERVISOR"> 
    You've ROLE_ADMIN AND ROLE_SUPERVISOR privileges. 
</sec:ifAllGranted> 

<!-- Check if user have at least one specified privileges --> 
<sec:ifAnyGranted roles="ROLE_ADMIN,ROLE_SUPERVISOR"> 
    You've ROLE_ADMIN OR ROLE_SUPERVISOR privileges. 
</sec:ifAnyGranted> 

</sec:ifLoggedIn> 

<sec:ifNotLoggedIn> 

It's public content, anonymous user. 

</sec:ifNotLoggedIn> 
... 

Вы также можете использовать: <sec:ifNotGranted roles="ROLE_USER"></sec:ifNotGranted>

Смежные вопросы