基于url的多语言登录页面

Posted

技术标签:

【中文标题】基于url的多语言登录页面【英文标题】:Multilanguage login page based on url 【发布时间】:2018-03-20 04:30:27 【问题描述】:

我在 Spring Boot 应用程序中将语言环境作为 url 的一部分:

/site - default locale

/en/site - English locale

我为此使用自定义拦截器:

    import org.springframework.beans.propertyeditors.LocaleEditor
    import org.springframework.util.Assert
    import org.springframework.web.servlet.handler.HandlerInterceptorAdapter
    import org.springframework.web.servlet.support.RequestContextUtils

    import javax.servlet.ServletException
    import javax.servlet.http.HttpServletRequest
    import javax.servlet.http.HttpServletResponse
    import java.util.Locale
    import java.util.regex.Pattern

    class CustomLocaleChangeInterceptor : HandlerInterceptorAdapter() 

    private var localePattern: Pattern? = null

    private fun setLocalePattern(localePattern: String) 
        Assert.isTrue(localePattern.matches(".*\\(.*\\).*".toRegex()), "Your pattern needs to define a match group")
        this.localePattern = Pattern.compile(localePattern)
    

    @Throws(ServletException::class)
    override fun preHandle(request: HttpServletRequest?, response: HttpServletResponse?, handler: Any?): Boolean 

        this.setLocalePattern("(en)")

        val pathTranslated = request!!.requestURI.substring(request.contextPath.length)

        if (pathTranslated.isNotEmpty()) 
            val matcher = localePattern!!.matcher(pathTranslated)
            if (matcher.find()) 
                resolver(request, response, matcher.group(1))
             else 
                resolver(request, response, "th")
            
        
        // Proceed in any case.
        return true

    

    private fun resolver(request: HttpServletRequest, response: HttpServletResponse?, locale: String) 
        val localeResolver = RequestContextUtils.getLocaleResolver(request) ?: throw IllegalStateException("No LocaleResolver found: not in a DispatcherServlet request?")
        val localeEditor = LocaleEditor()
        localeEditor.asText = locale
        localeResolver.setLocale(request, response, localeEditor.value as Locale)
    

问题是在 Spring 中处理两个自定义登录页面的最佳方式是什么?当受限 url 包含 /en 时,用户应重定向到 /en/login 页面(使用英语),否则如果页面具有默认语言环境,则应重定向到 /login url(使用默认语言)

【问题讨论】:

【参考方案1】:

同时我找到了这个解决方案。也许并不完美,但它确实有效。

@EnableWebSecurity
@Order(1)
class SecurityConfigTH : WebSecurityConfigurerAdapter() 

    private val localePattern: Pattern = Pattern.compile("^/en(\$|/)")

    @Throws(Exception::class)
    override fun configure(http: HttpSecurity) 
        http
                .authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                .requestMatcher  !localePattern.matcher(it.requestURI.toString()).find() 
                .formLogin()
                    .loginPage("/login")
                    .permitAll()
    


@EnableWebSecurity
@Order(2)
class SecurityConfigEN : WebSecurityConfigurerAdapter() 

    private val localePattern: Pattern = Pattern.compile("^/en(\$|/)")

    @Throws(Exception::class)
    override fun configure(http: HttpSecurity) 
        http
                .authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                .requestMatcher  localePattern.matcher(it.requestURI.toString()).find() 
                    .formLogin()
                    .loginPage("/en/login")
                    .permitAll()
    

【讨论】:

【参考方案2】:

在 spiring security 你可以使用这个

import java.io.IOException;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

    @Component
    public class Securityhandler implements AuthenticationSuccessHandler 

    public void onAuthenticationSuccess(HttpServletRequest request,   HttpServletResponse response, Authentication authentication) throws IOException  
    Local local= LocaleContextHolder.getLocale();
    if(local.equals("yourcodeLang")
       response.sendRedirect("/yourUrl");
    
    else // your logic
    
    

并像这样更新您的配置:

   @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
            .authorizeRequests()
              .anyRequest().authenticated()
              ....
              .successHandler(yourSuccessHandlerBean) // autowired or defined 
              ...
      

【讨论】:

谢谢Hicham,但据我了解,您的回答与成功身份验证后重定向用户的位置有关。我需要以相反的方式执行此操作:登录页面发送用户进行身份验证。

以上是关于基于url的多语言登录页面的主要内容,如果未能解决你的问题,请参考以下文章

浅谈web登录

EditText Android中的多语言问题

基于js的APP多语言处理

多语言网站的 Htaccess 和 url [关闭]

Kentico多语言网站

django-cms:反向 url 到一个/另一个 apphook - 多语言