【尚筹网】IDEA版实现(九)会员登录

由于尚硅谷的视频是通过Eclipse软件来做的,其中有些操作与IDEA上有所区别,所以我在这里将IDEA区别于Eclipse的操作、操作过程中涉及的源码(与视频的源码略有出入)以及大家可能遇到的种种问题分享给大家,这些源码在我这里均是通过测试的,仅供参考!

1 短信服务

1.1 短信服务测试

这部分需要自己去阿里云购买短信服务,每个人的api接口可能都不同,这里只上传我购买api的相关代码,把需要修改的几个地方标注出来的,具体操作请看视频!

修改authentication-consumer\pom.xml

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-test</artifactId>
    <scope>test</scope>
</dependency>

新建authentication-consumer\src\test\java\com\aiguigu\crowd\test\CrowdTest.java

package com.aiguigu.crowd.test;

import com.aliyun.api.gateway.demo.util.HttpUtils;
import org.apache.http.HttpResponse;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.HashMap;
import java.util.Map;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = CrowdTest.class)
public class CrowdTest {

    @Test
    public void testSendMessage() {

        String host = "https://cxkjsms.market.alicloudapi.com";
        String path = "/chuangxinsms/dxjk";
        String method = "POST";
        String appcode = "这部分需要自己填写";
        //开通服务后 买家中心-查看AppCode
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        Map<String, String> querys = new HashMap<String, String>();
        querys.put("content", "【创信】你的验证码是:5873,3分钟内有效!");
        querys.put("mobile", "填写自己手机号");
        Map<String, String> bodys = new HashMap<String, String>();


        try {
            /**
             * 重要提示如下:
             * HttpUtils请从
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
             * 下载
             *
             * 相应的依赖请参照
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
             */
            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            System.out.println(response.toString());
            //获取response的body
            //System.out.println(EntityUtils.toString(response.getEntity()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

新建authentication-consumer\src\main\java\com\aliyun\api\gateway\demo\util\HttpUtils.java

package com.aliyun.api.gateway.demo.util;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

public class HttpUtils {

    /**
     * get
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @return
     * @throws Exception
     */
    public static HttpResponse doGet(String host, String path, String method,
                                     Map<String, String> headers,
                                     Map<String, String> querys)
            throws Exception {
        HttpClient httpClient = wrapClient(host);

        HttpGet request = new HttpGet(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }

        return httpClient.execute(request);
    }

    /**
     * post form
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param bodys
     * @return
     * @throws Exception
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String, String> headers,
                                      Map<String, String> querys,
                                      Map<String, String> bodys)
            throws Exception {
        HttpClient httpClient = wrapClient(host);

        HttpPost request = new HttpPost(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }

        if (bodys != null) {
            List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();

            for (String key : bodys.keySet()) {
                nameValuePairList.add(new BasicNameValuePair(key, bodys.get(key)));
            }
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8");
            formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
            request.setEntity(formEntity);
        }

        return httpClient.execute(request);
    }

    /**
     * Post String
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String, String> headers,
                                      Map<String, String> querys,
                                      String body)
            throws Exception {
        HttpClient httpClient = wrapClient(host);

        HttpPost request = new HttpPost(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }

        if (StringUtils.isNotBlank(body)) {
            request.setEntity(new StringEntity(body, "utf-8"));
        }

        return httpClient.execute(request);
    }

    /**
     * Post stream
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String, String> headers,
                                      Map<String, String> querys,
                                      byte[] body)
            throws Exception {
        HttpClient httpClient = wrapClient(host);

        HttpPost request = new HttpPost(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }

        if (body != null) {
            request.setEntity(new ByteArrayEntity(body));
        }

        return httpClient.execute(request);
    }

    /**
     * Put String
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPut(String host, String path, String method,
                                     Map<String, String> headers,
                                     Map<String, String> querys,
                                     String body)
            throws Exception {
        HttpClient httpClient = wrapClient(host);

        HttpPut request = new HttpPut(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }

        if (StringUtils.isNotBlank(body)) {
            request.setEntity(new StringEntity(body, "utf-8"));
        }

        return httpClient.execute(request);
    }

    /**
     * Put stream
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPut(String host, String path, String method,
                                     Map<String, String> headers,
                                     Map<String, String> querys,
                                     byte[] body)
            throws Exception {
        HttpClient httpClient = wrapClient(host);

        HttpPut request = new HttpPut(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }

        if (body != null) {
            request.setEntity(new ByteArrayEntity(body));
        }

        return httpClient.execute(request);
    }

    /**
     * Delete
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @return
     * @throws Exception
     */
    public static HttpResponse doDelete(String host, String path, String method,
                                        Map<String, String> headers,
                                        Map<String, String> querys)
            throws Exception {
        HttpClient httpClient = wrapClient(host);

        HttpDelete request = new HttpDelete(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }

        return httpClient.execute(request);
    }

    private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
        StringBuilder sbUrl = new StringBuilder();
        sbUrl.append(host);
        if (!StringUtils.isBlank(path)) {
            sbUrl.append(path);
        }
        if (null != querys) {
            StringBuilder sbQuery = new StringBuilder();
            for (Map.Entry<String, String> query : querys.entrySet()) {
                if (0 < sbQuery.length()) {
                    sbQuery.append("&");
                }
                if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
                    sbQuery.append(query.getValue());
                }
                if (!StringUtils.isBlank(query.getKey())) {
                    sbQuery.append(query.getKey());
                    if (!StringUtils.isBlank(query.getValue())) {
                        sbQuery.append("=");
                        sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8"));
                    }
                }
            }
            if (0 < sbQuery.length()) {
                sbUrl.append("?").append(sbQuery);
            }
        }

        return sbUrl.toString();
    }

    private static HttpClient wrapClient(String host) {
        HttpClient httpClient = new DefaultHttpClient();
        if (host.startsWith("https://")) {
            sslClient(httpClient);
        }

        return httpClient;
    }

    private static void sslClient(HttpClient httpClient) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(X509Certificate[] xcs, String str) {

                }
                public void checkServerTrusted(X509Certificate[] xcs, String str) {

                }
            };
            ctx.init(null, new TrustManager[] { tm }, null);
            SSLSocketFactory ssf = new SSLSocketFactory(ctx);
            ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            ClientConnectionManager ccm = httpClient.getConnectionManager();
            SchemeRegistry registry = ccm.getSchemeRegistry();
            registry.register(new Scheme("https", 443, ssf));
        } catch (KeyManagementException ex) {
            throw new RuntimeException(ex);
        } catch (NoSuchAlgorithmException ex) {
            throw new RuntimeException(ex);
        }
    }
}

测试:运行testSendMessage(),可收到短信:

在这里插入图片描述

1.2 加入项目

修改util\src\main\java\com\atguigu\crowd\util\CrowdUtil.java

public static ResultEntity<String> sendShortMessage(String phoneNumbers) {

        String host = "https://cxkjsms.market.alicloudapi.com";
        String path = "/chuangxinsms/dxjk";
        String method = "POST";
        String appcode = "5ed7aeac19cf4c429048a1af7b603055";//开通服务后 买家中心-查看AppCode
        Map<String, String> headers = new HashMap<String, String>();

        // 生成验证码
        StringBuilder builder = new StringBuilder();
        for(int i = 0; i < 4; i++) {
            int random = (int) (Math.random() * 10);
            builder.append(random);
        }
        String code = builder.toString();

        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        Map<String, String> querys = new HashMap<String, String>();
        querys.put("content", "【创信】你的验证码是:"+ code +",3分钟内有效!");
        querys.put("mobile", phoneNumbers);
        Map<String, String> bodys = new HashMap<String, String>();


        try {
            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            StatusLine statusLine = response.getStatusLine();

            int statusCode = statusLine.getStatusCode();
            String reasonPhrase = statusLine.getReasonPhrase();

            if(statusCode == 200){
                return ResultEntity.successWithData(code);
            }

            return ResultEntity.failed(reasonPhrase);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

2 前往注册界面

2.1 创建view-controller

新建authentication-consumer\src\main\java\com\atguigu\crowd\config\CrowdWebMvcConfig.java

package com.atguigu.crowd.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CrowdWebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {

        // 浏览器访问的地址
        String urlPath = "/auth/member/to/reg/page.html";

        // 目标视图的名称,将来拼接前后缀
        String viewName = "member-reg";

        // 添加view-controller
        registry.addViewController(urlPath).setViewName(viewName);
    }
}

2.2 新建注册页面

修改authentication-consumer\src\main\resources\templates\portal.html

<li><a href="reg.html" th:href="@{/auth/member/to/reg/page.html}">注册</a></li>

新建authentication-consumer\src\main\resources\templates\member-reg.html

<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="keys" content="">
    <meta name="author" content="">
    <base th:href="@{/}"/>
    <link rel="stylesheet" href="bootstrap/css/bootstrap.css">
    <link rel="stylesheet" href="css/font-awesome.min.css">
    <link rel="stylesheet" href="css/login.css">
    <script src="jquery/jquery-3.6.0.js"></script>
    <script src="bootstrap/js/bootstrap.js"></script>
    <script type="text/javascript" src="layer/layer.js"></script>
    <script type="text/javascript">
        layer.msg("aaaa...");
    </script>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <div><a class="navbar-brand" href="index.html" style="font-size:32px;">尚筹网-创意产品众筹平台</a></div>
        </div>
    </div>
</nav>

<div class="container">

    <form class="form-signin" role="form">
        <h2 class="form-signin-heading"><i class="glyphicon glyphicon-log-in"></i> 用户注册</h2>
        <div class="form-group has-success has-feedback">
            <input type="text" class="form-control" id="inputSuccess4" placeholder="请输入登录账号" autofocus>
            <span class="glyphicon glyphicon-user form-control-feedback"></span>
        </div>
        <div class="form-group has-success has-feedback">
            <input type="text" class="form-control" id="inputSuccess4" placeholder="请输入登录密码" style="margin-top:10px;">
            <span class="glyphicon glyphicon-lock form-control-feedback"></span>
        </div>
        <div class="form-group has-success has-feedback">
            <input type="text" class="form-control" id="inputSuccess4" placeholder="请输入邮箱地址" style="margin-top:10px;">
            <span class="glyphicon glyphicon glyphicon-envelope form-control-feedback"></span>
        </div>
        <div class="form-group has-success has-feedback">
            <input type="text" class="form-control" id="inputSuccess4" placeholder="请输入手机号" style="margin-top:10px;">
            <span class="glyphicon glyphicon glyphicon-earphone form-control-feedback"></span>
        </div>
        <div class="form-group has-success has-feedback">
            <input type="text" class="form-control" id="inputSuccess4" placeholder="请输入验证码" style="margin-top:10px;">
            <span class="glyphicon glyphicon glyphicon-comment form-control-feedback"></span>
        </div>
        <button class="btn btn-lg btn-success btn-block"> 获取验证码</button>
        <a class="btn btn-lg btn-success btn-block" href="login.html" > 注册</a>
    </form>
</div>
</body>
</html>

2.3 发送验证码

2.3.1 前端部分

修改authentication-consumer\src\main\resources\templates\member-reg.html

<button id="sendBtn" type="button" class="btn btn-lg btn-success btn-block"> 获取验证码</button>
<input type="text" class="form-control" name="phoneNum" id="inputSuccess4" placeholder="请输入手机号" style="margin-top:10px;">
<script type="text/javascript">

    $(function (){
        $("#sendBtn").click(function (){
            // 1.获取接收短信的手机号
            var phoneNum = $.trim($("[name=phoneNum]").val());

            // 2.发送请求
            $.ajax({
                url: "auth/member/send/short/message.json",
                type: "post",
                data: {
                    phoneNum: phoneNum
                },
                dataType: "json",
                success: function (response){

                    var result = response.result;
                    if (result == "SUCCESS") {
                        layer.msg("发送成功");
                    }
                    if (result == "FAILED") {
                        layer.msg("发送失败!请再试一次!")
                    }
                },
                error: function (response){
                    layer.msg(response.status + " " + response.statusText);
                }
            });
        });
    });
</script>

2.3.2 后端部分

修改util\src\main\java\com\atguigu\crowd\constant\CrowdConstant.java

public static final String REDIS_CODE_PREFIX = "REDIS_CODE_PREFIX_";

新建consumer\src\main\java\com\atguigu\crowd\handler\MemberHandler.java

package com.atguigu.crowd.handler;

import com.atguigu.crowd.api.RedisRemoteService;
import com.atguigu.crowd.config.ShortMessageProperties;
import com.atguigu.crowd.constant.CrowdConstant;
import com.atguigu.crowd.util.CrowdUtil;
import com.atguigu.crowd.util.ResultEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.concurrent.TimeUnit;

@Controller
public class MemberHandler {

    @Autowired
    private ShortMessageProperties shortMessageProperties;

    @Autowired
    private RedisRemoteService redisRemoteService;

    @ResponseBody
    @RequestMapping("/auth/member/send/short/message.json")
    public ResultEntity<String> sendMessage(@RequestParam("phoneNum") String phoneNum) {

        // 1.发送验证码到phoneNum手机
        ResultEntity<String> sendMessageResultEntity = CrowdUtil.sendShortMessage(
                shortMessageProperties.getHost(),
                shortMessageProperties.getPath(),
                shortMessageProperties.getMethod(), phoneNum,
                shortMessageProperties.getAppCode());

        // 2.判断是否发送成功
        if (ResultEntity.SUCCESS.equals(sendMessageResultEntity.getResult())) {

            // 3.如果成功,则将验证码存入Redis
            String code = sendMessageResultEntity.getData();
            String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;
            ResultEntity<String> saveCodeResultEntity = redisRemoteService.setRedisKeyValueRemoteWithTimeout(key, code, 15, TimeUnit.MINUTES);


            // 4. 判断是否成功存入 Redis
            if (ResultEntity.SUCCESS.equals(saveCodeResultEntity.getResult())) {
                return ResultEntity.successWithoutData();
            }else {
                return saveCodeResultEntity;
            }
        }else {
            return sendMessageResultEntity;
        }
    }
}

新建authentication-consumer\src\main\java\com\atguigu\crowd\config\ShortMessageProperties.java

package com.atguigu.crowd.config;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@NoArgsConstructor
@AllArgsConstructor
@Data
@Component
@ConfigurationProperties(prefix = "short.message")
public class ShortMessageProperties {

    private String host;
    private String path;
    private String method;
    private String appCode;

}

修改authentication-consumer\src\main\resources\application.yml

short:
  message:
    app-code: 5ed7aeac19cf4c429048a1af7b603055
    host: https://cxkjsms.market.alicloudapi.com
    method: POST
    path: /chuangxinsms/dxjk

修改authentication-consumer\src\main\java\com\atguigu\crowd\CrowdMainClass.java

@EnableFeignClients

2.3.3 测试

可以正常收到短信,并将映射记录在redis中:

在这里插入图片描述
在这里插入图片描述

注:1和2由于每个人所购买的api不同,所以代码部分也不尽相同,这部分仅供思路参考,尽量不要随意CV!

另:测试时可能会包ResultEntity类构造器缺失,可通过将lombok类import至util\src\main\java\com\atguigu\crowd\util\ResultEntity.java来解决:

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor

3 用户注册

3.1 SQL存储

在SQLyog给loginacct增加唯一约束:

ALTER TABLE `project_crowd`.`t_member` ADD UNIQUE INDEX (`loginacct`); 

修改mysql-provider\src\main\java\com\atguigu\crowd\handler\MemberProviderHandler.java

@RequestMapping("/save/member/remote")
public ResultEntity<String> saveMember(@RequestBody MemberPO memberPO) {

    try {
        memberService.saveMember(memberPO);

        return ResultEntity.successWithoutData();
    } catch (Exception e) {

        if (e instanceof DuplicateKeyException)
            return ResultEntity.failed(CrowdConstant.MESSAGE_LOGIN_ACCT_ALREADY_IN_USE);

        return ResultEntity.failed(e.getMessage());
    }
}

并新增saveMember()方法及实现类:

修改mysql-provider\src\main\java\com\atguigu\crowd\service\impl\MemberServiceImpl.java

@Transactional(
    propagation = Propagation.REQUIRES_NEW,
    rollbackFor = Exception.class,
    readOnly = false)
@Override
public void saveMember(MemberPO memberPO) {

    memberPOMapper.insertSelective(memberPO);
}

修改api\src\main\java\com\atguigu\crowd\api\MySQLRemoteService.java

@RequestMapping("/save/member/remote")
public ResultEntity<String> saveMember(@RequestBody MemberPO memberPO);

3.2 测试

使用Postman,设置POST地址:

http://localhost:2000/save/member/remote

请求头:

Content-Type:application/json;charset=UTF-8

请求体:

{
	"loginacct":"Heygo",
	"userpswd":123123
}

在这里插入图片描述
在这里插入图片描述

再次提交:

在这里插入图片描述

查看SQLyog:

在这里插入图片描述

3.3 auth-consumer

修改authentication-consumer\src\main\resources\templates\member-reg.html

<div class="container">

    <form action="/auth/do/member/register" method="post" class="form-signin" role="form">
        <h2 class="form-signin-heading"><i class="glyphicon glyphicon-log-in"></i> 用户注册</h2>
        <p th:text="${message}">这里显示从请求域取出的提示消息</p>
        <div class="form-group has-success has-feedback">
            <input type="text" name="loginacct" class="form-control" id="inputSuccess4" placeholder="请输入登录账号" autofocus>
            <span class="glyphicon glyphicon-user form-control-feedback"></span>
        </div>
        <div class="form-group has-success has-feedback">
            <input type="text" name="userpswd" class="form-control" id="inputSuccess4" placeholder="请输入登录密码" style="margin-top: 10px;">
            <span class="glyphicon glyphicon-lock form-control-feedback"></span>
        </div>
        <div class="form-group has-success has-feedback">
            <input type="text" name="username" class="form-control" id="inputSuccess4" placeholder="请输入用户昵称" style="margin-top: 10px;">
            <span class="glyphicon glyphicon-lock form-control-feedback"></span>
        </div>
        <div class="form-group has-success has-feedback">
            <input type="text" name="email" class="form-control" id="inputSuccess4" placeholder="请输入邮箱地址" style="margin-top: 10px;">
            <span class="glyphicon glyphicon glyphicon-envelope form-control-feedback"></span>
        </div>
        <div class="form-group has-success has-feedback">
            <input type="text" name="phoneNum" class="form-control" id="inputSuccess4" placeholder="请输入手机号" style="margin-top: 10px;">
            <span class="glyphicon glyphicon glyphicon-earphone form-control-feedback"></span>
        </div>
        <div class="form-group has-success has-feedback">
            <input type="text" name="code" class="form-control" id="inputSuccess4" placeholder="请输入验证码" style="margin-top: 10px;">
            <span class="glyphicon glyphicon glyphicon-comment form-control-feedback"></span>
        </div>
        <button id="sendBtn" type="button" class="btn btn-lg btn-success btn-block"> 获取验证码</button>
        <button type="submit" class="btn btn-lg btn-success btn-block">注册</button>
    </form>
</div>

新建authentication-consumer\src\main\java\com\atguigu\crowd\handler\MemberHandler.java

@Autowired
private MySQLRemoteService mySQLRemoteService;

@RequestMapping("/auth/do/member/register")
public String register(MemberVO memberVO, ModelMap modelMap) {


    // 1.获取用户输入的手机号
    String phoneNum = memberVO.getPhoneNum();

    // 2.拼接Redis中存储的Key
    String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;

    // 3.从Redis读取Key对应的value
    ResultEntity<String> resultEntity = redisRemoteService.getRedisStringValueByKeyRemote(key);

    // 4.检查查询操作是否有效
    String result = resultEntity.getResult();
    if (ResultEntity.FAILED.equals(result)) {

        modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, resultEntity.getMessage());
        return "member-reg";
    }

    String redisCode = resultEntity.getData();
    if (redisCode == null) {
        modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_NOT_EXISTS);
        return "member-reg";
    }

    // 5.能从Redis查询到,则比较两者是否一致
    String formCode = memberVO.getCode();
    if (!formCode.equals(redisCode)) {

        modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_INVALID);
        return "member-reg";
    }
    // 6.一致,将value从Redis中删除
    ResultEntity<String> removeResultEntity = redisRemoteService.removeRedisKeyRemote(key);

    // 7.执行密码加密
    BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    String userpswdBeforeEncode = memberVO.getUserpswd();
    String userpswdAfterEncode = passwordEncoder.encode(userpswdBeforeEncode);
    memberVO.setUserpswd(userpswdAfterEncode);

    // 8. 执行保存
    MemberPO memberPO = new MemberPO();
    BeanUtils.copyProperties(memberVO, memberPO);
    ResultEntity<String> saveMemberResultEntity = mySQLRemoteService.saveMember(memberPO);

    if (ResultEntity.FAILED.equals(saveMemberResultEntity)) {

        modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, saveMemberResultEntity.getMessage());

        return "member-reg";
    }

    return "redirect:/auth/member/to/login/page";
}

修改util\src\main\java\com\atguigu\crowd\constant\CrowdConstant.java

public static final String MESSAGE_CODE_NOT_EXISTS = "验证码已过期!请检查手机号是否正确或重新发送!";
public static final String MESSAGE_CODE_INVALID = "验证码不正确!";

修改authentication-consumer\src\main\resources\application.yml

ribbon:
  ConnectTimeout: 10000 # 连接超时时间(ms)
  ReadTimeout: 10000 # 通信超时时间(ms)

修改authentication-consumer\src\main\java\com\atguigu\crowd\config\CrowdWebMvcConfig.java

registry.addViewController("/auth/member/to/login/page").setViewName("member-login");

新建authentication-consumer\src\main\resources\templates\member-login.html

不用写东西,先完成下列测试

3.4 测试

在这里插入图片描述

输入正确验证码后,进入创建的login界面:

在这里插入图片描述

注册后可在SQLyog中查询到数据:

在这里插入图片描述

如果输入错误手机号:

在这里插入图片描述

如果输入错误验证码:

在这里插入图片描述

如果输入同样的登录账号:

在这里插入图片描述

4 用户登录

4.1 前端部分

修改authentication-consumer\src\main\resources\templates\member-login.html

<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="keys" content="">
    <meta name="author" content="">
    <base th:href="@{/}"/>
    <link rel="stylesheet" href="bootstrap/css/bootstrap.css">
    <link rel="stylesheet" href="css/font-awesome.min.css">
    <link rel="stylesheet" href="css/login.css">
    <script src="jquery/jquery-3.6.0.js"></script>
    <script src="bootstrap/js/bootstrap.js"></script>
    <style>
    </style>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <div><a class="navbar-brand" href="index.html" style="font-size:32px;">尚筹网-创意产品众筹平台</a></div>
        </div>
    </div>
</nav>

<div class="container">

    <form action="/auth/member/do/login" method="post" class="form-signin" role="form">
        <h2 class="form-signin-heading">
            <i class="glyphicon glyphicon-log-in"></i> 用户登录
        </h2>
        <p th:text="${message}">在这里显示登录失败的提示消息</p>
        <div class="form-group has-success has-feedback">
            <input type="text" name="loginacct" class="form-control" id="loginacct" placeholder="请输入登录账号" autofocus>
            <span class="glyphicon glyphicon-user form-control-feedback"></span>
        </div>
        <div class="form-group has-success has-feedback">
            <input type="text" name="userpswd" class="form-control" id="userpswd" placeholder="请输入登录密码" style="margin-top:10px;">
            <span class="glyphicon glyphicon-lock form-control-feedback"></span>
        </div>
        <div class="checkbox" style="text-align:right;">
            <a href="reg.html" th:href="@{/auth/member/to/login/page/}">我要注册</a>
        </div>
        <button type="submit" class="btn btn-lg btn-success btn-block"> 登录</button>
    </form>
</div>
</body>
</html>

修改authentication-consumer\src\main\resources\templates\portal.html

<li><a href="login.html" th:href="@{/auth/member/to/login/page}">登录</a></li>

4.2 后端部分

新建entity\src\main\java\com\atguigu\crowd\entity\vo\MemberLoginVO.java

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class MemberLoginVO {

    private Integer id;

    private String username;

    private String email;
}

修改authentication-consumer\src\main\java\com\atguigu\crowd\handler\MemberHandler.java

@RequestMapping("/auth/member/do/login")
public String doLogin(@RequestParam("loginacct") String logincacct,
                      @RequestParam("userpswd") String userpswd,
                      ModelMap modelMap,
                      HttpSession session) {

    // 1.调用远程接口查询登录账号
    ResultEntity<MemberPO> resultEntity = mySQLRemoteService.getMemberPOByLoginAcctRemote(logincacct);

    // 2.失败则返回登录页面
    if (ResultEntity.FAILED.equals(resultEntity.getResult())) {
        modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, resultEntity.getMessage());
        return "member-login";
    }

    MemberPO memberPO = resultEntity.getData();

    if (memberPO == null) {
        modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_LOGIN_FAILED);
        return "member-login";
    }

    // 3.比较密码
    String userpswdDataBase = memberPO.getUserpswd();
    BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    boolean matches = passwordEncoder.matches(userpswd, userpswdDataBase);
    if (!matches) {
        modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_LOGIN_FAILED);
        return "member-login";
    }

    // 4.创建MemberLoginVO对象存入Session域
    MemberLoginVO memberLoginVO = new MemberLoginVO(memberPO.getId(), memberPO.getUsername(), memberPO.getEmail());
    session.setAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER, memberLoginVO);

    return "redirect:/auth/member/to/center/page";
}

修改util\src\main\java\com\atguigu\crowd\constant\CrowdConstant.java

public static final String ATTR_NAME_LOGIN_MEMBER = "loginMember";

新建authentication-consumer\src\main\resources\templates\member-center.html

<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <base th:href="@{/}"/>
    <link rel="stylesheet" href="bootstrap/css/bootstrap.css">
    <link rel="stylesheet" href="css/font-awesome.min.css">
    <link rel="stylesheet" href="css/theme.css">
    <script src="jquery/jquery-3.6.0.js"></script>
    <script src="bootstrap/js/bootstrap.js"></script>
    <script src="script/docs.min.js"></script>
    <script src="script/back-to-top.js"></script>
    <script src="script/echarts.js"></script>
    <style>
        #footer {
            padding: 15px 0;
            background: #fff;
            border-top: 1px solid #ddd;
            text-align: center;
        }
        #topcontrol {
            color: #fff;
            z-index: 99;
            width: 30px;
            height: 30px;
            font-size: 20px;
            background: #222;
            position: relative;
            right: 14px !important;
            bottom: 11px !important;
            border-radius: 3px !important;
        }

        #topcontrol:after {
            /*top: -2px;*/
            left: 8.5px;
            content: "\f106";
            position: absolute;
            text-align: center;
            font-family: FontAwesome;
        }

        #topcontrol:hover {
            color: #fff;
            background: #18ba9b;
            -webkit-transition: all 0.3s ease-in-out;
            -moz-transition: all 0.3s ease-in-out;
            -o-transition: all 0.3s ease-in-out;
            transition: all 0.3s ease-in-out;
        }

    </style>
</head>
<body>
<div class="navbar-wrapper">
    <div class="container">
        <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
            <div class="container">
                <div class="navbar-header">
                    <a class="navbar-brand" href="index.html" style="font-size:32px;">尚筹网-创意产品众筹平台</a>
                </div>
                <div id="navbar" class="navbar-collapse collapse" style="float:right;">
                    <ul class="nav navbar-nav">
                        <li class="dropdown">
                            <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="glyphicon glyphicon-user"></i> [[${session.loginMember.username}]]<span class="caret"></span></a>
                                <li><a href="member.html"><i class="glyphicon glyphicon-scale"></i> 会员中心</a></li>
                                <li><a href="#"><i class="glyphicon glyphicon-comment"></i> 消息</a></li>
                                <li class="divider"></li>
                                <li><a href="index.html"><i class="glyphicon glyphicon-off"></i> 退出系统</a></li>
                            </ul>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>

    </div>
</div>
<div class="container">
    <div class="row clearfix">
        <div class="col-sm-3 col-md-3 column">
            <div class="row">
                <div class="col-md-12">
                    <div class="thumbnail" style="    border-radius: 0px;">
                        <img src="img/services-box1.jpg" class="img-thumbnail" alt="">
                        <div class="caption" style="text-align:center;">
                            <h3>
                                [[${session.loginMember.username}]]
                            </h3>
                            <span class="label label-danger" style="cursor:pointer;" onclick="window.location.href='accttype.html'">未实名认证</span>
                        </div>
                    </div>
                </div>
            </div>
            <div class="list-group">
                <div class="list-group-item active">
                    资产总览<span class="badge"><i class="glyphicon glyphicon-chevron-right"></i></span>
                </div>
                <div class="list-group-item " style="cursor:pointer;" onclick="window.location.href='minecrowdfunding.html'">
                    我的众筹<span class="badge"><i class="glyphicon glyphicon-chevron-right"></i></span>
                </div>
            </div>
        </div>
        <div class="col-sm-9 col-md-9 column">
            <blockquote style="border-left: 5px solid #f60;color:#f60;padding: 0 0 0 20px;">
                <b>
                    我的钱包
                </b>
            </blockquote>
            <div id="main" style="width: 600px;height:400px;"></div>
            <blockquote style="border-left: 5px solid #f60;color:#f60;padding: 0 0 0 20px;">
                <b>
                    理财
                </b>
            </blockquote>
            <div id="main1" style="width: 600px;height:400px;"></div>
            <blockquote style="border-left: 5px solid #f60;color:#f60;padding: 0 0 0 20px;">
                <b>
                    比例
                </b>
            </blockquote>
            <div id="main2" style="width: 600px;height:400px;"></div>
        </div>
    </div>
</div>
<div class="container" style="margin-top:20px;">
    <div class="row clearfix">
        <div class="col-md-12 column">
            <div id="footer">
                <div class="footerNav">
                    <a rel="nofollow" href="http://www.atguigu.com">关于我们</a> | <a rel="nofollow" href="http://www.atguigu.com">服务条款</a> | <a rel="nofollow" href="http://www.atguigu.com">免责声明</a> | <a rel="nofollow" href="http://www.atguigu.com">网站地图</a> | <a rel="nofollow" href="http://www.atguigu.com">联系我们</a>
                </div>
                <div class="copyRight">
                    Copyright ?2017-2017atguigu.com 版权所有
                </div>
            </div>

        </div>
    </div>
</div>
<script>
    $('#myTab a').click(function (e) {
        e.preventDefault()
        $(this).tab('show')
    })
    $('#myTab1 a').click(function (e) {
        e.preventDefault()
        $(this).tab('show')
    })

    var myChart = echarts.init(document.getElementById('main'));

    // 指定图表的配置项和数据
    option = {
        title: {
            text: '七日年化收益率(%)'
        },
        tooltip: {
            trigger: 'axis'
        },
        legend: {
            data:['基金','股票']
        },
        toolbox: {
            show: false,
            feature: {
                dataZoom: {
                    yAxisIndex: 'none'
                },
                dataView: {readOnly: false},
                magicType: {type: ['line', 'bar']},
                restore: {},
                saveAsImage: {}
            }
        },
        xAxis:  {
            type: 'category',
            boundaryGap: false,
            data: ['2017-05-16','2017-05-17','2017-05-18','2017-05-19','2017-05-20','2017-05-21','2017-05-22']
        },
        yAxis: {
            type: 'value',
            axisLabel: {
                formatter: '{value} '
            }
        },
        series: [
            {
                name:'基金',
                type:'line',
                data:[1, 1, 5, 3, 2, 3, 2],
                markPoint: {
                    data: [
                        {type: 'max', name: '最大值'},
                        {type: 'min', name: '最小值'}
                    ]
                },
                markLine: {
                    data: [
                        {type: 'average', name: '平均值'}
                    ]
                }
            },
            {
                name:'股票',
                type:'line',
                data:[1, -2, 2, 5, 3, 2, 4],
                markPoint: {
                    data: [
                        {name: '周最低', value: -2, xAxis: 1, yAxis: -1.5}
                    ]
                },
                markLine: {
                    data: [
                        {type: 'average', name: '平均值'},
                        [{
                            symbol: 'none',
                            x: '90%',
                            yAxis: 'max'
                        }, {
                            symbol: 'circle',
                            label: {
                                normal: {
                                    position: 'start',
                                    formatter: '最大值'
                                }
                            },
                            type: 'max',
                            name: '最高点'
                        }]
                    ]
                }
            }
        ]
    };
    myChart.setOption(option);
    var myChart1 = echarts.init(document.getElementById('main1'));

    // 指定图表的配置项和数据
    option1 = {
        color: ['#3398DB'],
        tooltip : {
            trigger: 'axis',
            axisPointer : {            // 坐标轴指示器,坐标轴触发有效
                type : 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
            }
        },
        grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            containLabel: true
        },
        xAxis : [
            {
                type : 'category',
                data : ['基金', '票据', '定期理财', '变现贷'],
                axisTick: {
                    alignWithLabel: true
                }
            }
        ],
        yAxis : [
            {
                type : 'value'
            }
        ],
        series : [
            {
                name:'直接访问',
                type:'bar',
                barWidth: '60%',
                data:[10, 52, 200, 334, 390, 330, 220]
            }
        ]
    };

    // 使用刚指定的配置项和数据显示图表。
    myChart1.setOption(option1);

    var myChart2 = echarts.init(document.getElementById('main2'));

    // 指定图表的配置项和数据
    option2 = {
        title : {
            text: '某站点用户访问来源',
            subtext: '纯属虚构',
            x:'center'
        },
        tooltip : {
            trigger: 'item',
            formatter: "{a} <br/>{b} : {c} ({d}%)"
        },
        legend: {
            orient: 'vertical',
            left: 'left',
            data: ['直接访问','邮件营销','联盟广告','视频广告','搜索引擎']
        },
        series : [
            {
                name: '访问来源',
                type: 'pie',
                radius : '55%',
                center: ['50%', '60%'],
                data:[
                    {value:335, name:'直接访问'},
                    {value:310, name:'邮件营销'},
                    {value:234, name:'联盟广告'},
                    {value:135, name:'视频广告'},
                    {value:1548, name:'搜索引擎'}
                ],
                itemStyle: {
                    emphasis: {
                        shadowBlur: 10,
                        shadowOffsetX: 0,
                        shadowColor: 'rgba(0, 0, 0, 0.5)'
                    }
                }
            }
        ]
    };

    // 使用刚指定的配置项和数据显示图表。
    myChart2.setOption(option2);
</script>
</body>
</html>

修改authentication-consumer\src\main\java\com\atguigu\crowd\config\CrowdWebMvcConfig.java

registry.addViewController("/auth/member/to/center/page").setViewName("member-center");

修改mysql-provider\src\main\java\com\atguigu\crowd\service\impl\MemberServiceImpl.java

// 5.获取结果
if(list == null || list.size() == 0){
    return null;
}
return list.get(0);

4.3 测试

如果输入错误的账号或者密码,则提示:

在这里插入图片描述

如果输入正确,则进入:

在这里插入图片描述

4.4 退出登录

修改authentication-consumer\src\main\resources\templates\member-center.html

<li><a href="index.html" th:href="@{/auth/member/logout}"><i class="glyphicon glyphicon-off"></i> 退出系统</a></li>

修改authentication-consumer\src\main\java\com\atguigu\crowd\handler\MemberHandler.java

@RequestMapping("/auth/member/logout")
public String logout(HttpSession session) {
    session.invalidate();
    return "redirect:/";
}

测试:在点击退出系统后可以退回界面

在这里插入图片描述

5 登录状态检查

5.1 Pom配置

修改authentication-consumer\pom.xml以及zuul\pom.xml

<!-- 引入springboot&redis整合场景 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 引入springboot&springsession整合场景 -->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>

5.2 Application

修改zuul\src\main\resources\application.yml

spring:
  application:
    name: atguigu-crowd-zuul
  redis:
    host: 192.168.201.100
  session:
    store-type: redis

修改zuul\src\main\resources\application.yml

spring:
  application:
    name: atguigu-crowd-auth
  thymeleaf:
    prefix: classpath:/templates/
    suffix: .html
  redis:
    host: 127.0.0.1
  session:
    store-type: redis

5.3 放行静态资源

新建util\src\main\java\com\atguigu\crowd\constant\AccessPassResources.java

package com.atguigu.crowd.constant;

import java.util.HashSet;
import java.util.Set;

public class AccessPassResources {

    public static final Set<String> PASS_RES_SET = new HashSet<>();

    static {
        PASS_RES_SET.add("/");
        PASS_RES_SET.add("/auth/member/to/reg/page");
        PASS_RES_SET.add("/auth/member/to/login/page");
        PASS_RES_SET.add("/auth/member/logout");
        PASS_RES_SET.add("/auth/member/do/login");
        PASS_RES_SET.add("/auth/do/member/register");
        PASS_RES_SET.add("/auth/member/send/short/message.json");
    }

    public static final Set<String> STATIC_RES_SET = new HashSet<>();

    static {
        STATIC_RES_SET.add("bootstrap");
        STATIC_RES_SET.add("css");
        STATIC_RES_SET.add("fonts");
        STATIC_RES_SET.add("img");
        STATIC_RES_SET.add("jquery");
        STATIC_RES_SET.add("layer");
        STATIC_RES_SET.add("script");
        STATIC_RES_SET.add("ztree");
    }

    /**
     * 用于判断某个 ServletPath 值是否对应一个静态资源
     * @param servletPath
     * @return
     *      true:是静态资源
     *      false:不是静态资源
     */
    public static boolean judgeCurrentServletPathWhetherStaticResource(String servletPath) {

        if (servletPath == null || servletPath.length() == 0) {
            throw new RuntimeException(CrowdConstant.MESSAGE_STRING_INVALIDATE);
        }

        String[] split = servletPath.split("/");

        String firstLevelPath = split[1];

        return STATIC_RES_SET.contains(firstLevelPath);
    }
}

5.4 Zuul filter

新建zuul\src\main\java\com\atguigu\crowd\filter\CrowdAccessFilter.java

package com.atguigu.crowd.filter;

import com.atguigu.crowd.constant.AccessPassResources;
import com.atguigu.crowd.constant.CrowdConstant;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@Component
public class CrowdAccessFilter extends ZuulFilter {

    @Override
    public boolean shouldFilter() {

        // 1.获取RequestContext对象
        RequestContext requestContext = RequestContext.getCurrentContext();

        // 2.通过RequestContext对象获取当前请求对象( 框架底层是借助 ThreadLocal 从当前线程上获取事先绑定的 Request 对象)
        HttpServletRequest request = requestContext.getRequest();

        // 3.获取 servletPath 值
        String servletPath = request.getServletPath();

        // 4.根据 servletPath 判断当前请求是否对应可以直接放行的特定功能
        boolean containsResult = AccessPassResources.PASS_RES_SET.contains(servletPath);
        // 如果当前请求是可以直接放行的特定功能请求则返回 false 放行
        if (containsResult){
            return false;
        }

        // 5.判断当前请求是否为静态资源
        return !AccessPassResources.judgeCurrentServletPathWhetherStaticResource(servletPath);
    }

    @Override
    public Object run() throws ZuulException {

        // 1.获取当前请求对象
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();

        // 2.获取当前Session对象
        HttpSession session = request.getSession();

        // 3.尝试从 Session 对象中获取已登录用户
        Object loginMember = session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER);

        // 4.判断 loginMember 是否为空
        if (loginMember == null) {

            // 5.从requestContext对象中获取Response对象
            HttpServletResponse response = requestContext.getResponse();

            // 6.将提示消息存入session域
            session.setAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_ACCESS_FORBIDDEN);

            // 7.重定向到 auth-consumer 工程中的登录页面
            try {
                response.sendRedirect("/auth/member/to/login/page");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }
}

5.5 其余改动

修改authentication-consumer\src\main\resources\templates\member-login.html

<p th:text="${session.message}">在这里显示登录失败的提示消息</p>

5.6 测试

直接输入http://localhost/auth/member/to/login/page或者http://localhost:4000/auth/member/to/login/page,均会被弹出并显示:

在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值