Part 7 - 扩展功能实现

2021-11-11
5分钟阅读时长

【版本】

当前版本号v20211111

版本修改说明
v20211111初始化版本

【实验名称】 实验7.1 完善用户密码加密功能

【实验目的】

  • 掌握密码加密的编程和实现

【实验环境】

  • 内存:至少4G
  • 硬盘:至少空余10G
  • 操作系统: 64位 Windows系统。

【实验资源】

下载地址:

链接:https://pan.baidu.com/s/1qy0QpYbG_dWT8fKx3ZjvnQ 
提取码:heis

【实验说明】

  1. 作为企业级应用,存储用户的明文密码是非常不专业而且充满安全风险的行为。因此我们要对用户的密码进行单向的加密(通过密文无法反向推出明文)。单向加密一般使用消息摘要算法实现,常见的消息摘要算法有以下几种:
  • MD 系列算法包括 MD2、MD4 和 MD5 共 3 种算法。但是 MD5 已经在 2004 年被证明存在冲突,已不适用于安全认证。
  • SHA 算法主要包括其代表算法 SHA-1 和 SHA-1 算法的变种 SHA-2 系列算法(包含 SHA-224、SHA-256、SHA-384 和 SHA-512);
  • MAC 算法综合了上述两种算法,主要包括 HmacMD5、HmacSHA1、HmacSHA256、HmacSHA384 和 HmacSHA512 算法。
  1. 单向加密的常用做法,是通过给用户明文密码加上一个随机的字符串(salt,中文翻译为盐)。然后再对加盐的密码进行单向加密。得到密文再加盐,再次进行单向加密。如此循环数次,再存储最终的密文,达到较为安全的加密效果。
//第1次加密
密文1=加密算法计算(明文密码+盐)

//第2次加密
密文2=加密算法计算(密文1+盐)

...

第N次加密
密文N=加密算法计算(密文(N-1)+盐)

【实验要求】

  1. 完善用户的密码加密功能。表tab_user 增加字段salt,用于存储。同时修改tab_user 增加字段password的长度为128。请在src/main/resources/db/migration 目录下新增 SQL 脚本完成对数据库的修改。
字段修改说明
tab_user.salt新增,可变长字符串,最大长度8
tab_user.password修改,长度修改为128
  1. 修改原有明文存储的代码,修改为通过加盐(随机字符串)和使用 SHA-256 循环3次实现加密,并把密文存储在tab_user.password字段,盐存储在tab_user.salt字段。

【实验提示和注意事项】

  1. 增加数据库字段以后注意修改实体类 User

  2. SHA256 加密方法。

  • pom.xml 增加依赖
<dependency>
  <groupId>commons-codec</groupId>
  <artifactId>commons-codec</artifactId>
  <version>1.11</version>
</dependency>
  • SHA256 加密实现
package com.zjtec.travel.util;

import com.alibaba.druid.sql.visitor.functions.Hex;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MsgDigestUtils {
  /**
   * SHA256 加密
   * @param str 明文
   * @return 密文
   */
  public static String encodeSHA256(String str){
    MessageDigest messageDigest;
    String encdeStr = "";
    try {
      messageDigest = MessageDigest.getInstance("SHA-256");
      byte[] hash = messageDigest.digest(str.getBytes("UTF-8"));
      encdeStr = byte2Hex(hash);
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return encdeStr;
  }

  private static String byte2Hex(byte[] bytes){
    StringBuffer stringBuffer = new StringBuffer();
    String temp = null;
    for (int i=0;i<bytes.length;i++){
      temp = Integer.toHexString(bytes[i] & 0xFF);
      if (temp.length()==1){
        //1得到一位的进行补0操作
        stringBuffer.append("0");
      }
      stringBuffer.append(temp);
    }
    return stringBuffer.toString();
  }

}

【实验名称】 实验7.2 完成旅游产品详细信息页面动态数据加载

【实验目的】

  • 掌握 SSM 的编程和实现

【实验环境】

  • 内存:至少4G
  • 硬盘:至少空余10G
  • 操作系统: 64位 Windows系统。

【实验资源】

下载地址:

链接:https://pan.baidu.com/s/1lwTbxGGCKKzC7TPXSgeVzQ 
提取码:heis

【实验要求】

  1. 目前用户点击旅游产品的查看详情,调转到的链接是一个静态的页面。http://localhost:8082/route_detail.html。请完善该功能,实现点击某项旅游产品的查看详情可以跳转到旅游产品的详细信息页面,并真正加载对应的产品的信息(下图2中红框的部分都是动态内容)。

【实验提示和注意事项】

  1. 该功能涉及到获取2个表格的数据,分别是tab_routetab_seller,以下为2个表字段说明。
  • tab_route旅游产品信息表
字段说明
rid旅游产品唯一ID
rname产品名称
price价格
routeIntroduce产品介绍
cid产品目录ID
rimage产品图片
sid经营商家ID
  • tab_seller经营商家信息表
字段说明
sid唯一ID
sname经营商家名称
consphone经营商家联系方式
address经营商家地址

【实验名称】 实验7.3 完成邮件发送功能

【实验目的】

  • 掌握发送邮件的相关的编程和实现

【实验环境】

  • 内存:至少4G
  • 硬盘:至少空余10G
  • 操作系统: 64位 Windows系统。

【实验资源】

下载地址:

链接:https://pan.baidu.com/s/1qy0QpYbG_dWT8fKx3ZjvnQ 
提取码:heis

【实验要求】

  1. 实现邮件的发送功能。邮件的发送需要我们准备一个发送方的邮箱,这里推荐使用139 邮箱。点击这里注册

  2. 注册邮箱以后,勾选开启IMAP/SMTP服务,并生成授权码,注意记录你授权码。

  3. 在用户注册成功以后,给用户发送激活邮件,邮件内附激活链接。

【实验提示和注意事项】

  1. 发送邮件的代码参考。注意注入的各个属性的设置。
package com.zjtec.travel.service.impl;

import com.zjtec.travel.service.EmailService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;

@Service
public class EmailServiceImpl implements EmailService {

  private final static Logger log= LoggerFactory.getLogger(EmailServiceImpl.class);

  @Value("#{email.smtphost}")
  private String smtpHost;//SMTP 地址,例如smtp.139.com

  @Value("#{email.username}")
  private String username;//发送方邮箱地址

  @Value("#{email.password}")
  private String password;//密码或授权码

  @Value("#{email.smtpauth}")
  private String smtpAuth;//设置为true

  /**
   * 发送邮件
   * @param sendTo 对方邮箱地址
   * @param title 邮件标题
   * @param content 邮件内容
   */
  @Override
  public void sendEmail(String sendTo, String title, String content) {
    try {
      final Properties props = new Properties();
      props.put("mail.smtp.auth", smtpAuth);
      props.put("mail.smtp.host", smtpHost);
      // 发件人的账号
      props.put("mail.user", username);
      //发件人的密码
      props.put("mail.password", password);

      // 构建授权信息,用于进行SMTP进行身份验证
      Authenticator authenticator = new Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
          // 用户名、密码
          String userName = props.getProperty("mail.user");
          String password = props.getProperty("mail.password");
          return new PasswordAuthentication(userName, password);
        }
      };
      // 使用环境属性和授权信息,创建邮件会话
      Session mailSession = Session.getInstance(props, authenticator);
      // 创建邮件消息
      MimeMessage message = new MimeMessage(mailSession);
      // 设置发件人
      String username = props.getProperty("mail.user");
      InternetAddress form = new InternetAddress(username);
      message.setFrom(form);

      // 设置收件人
      InternetAddress toAddress = new InternetAddress(sendTo);
      message.setRecipient(Message.RecipientType.TO, toAddress);

      // 设置邮件标题
      message.setSubject(title);

      // 设置邮件的内容体
      message.setContent(content, "text/html;charset=UTF-8");
      // 发送邮件
      Transport.send(message);
    } catch (Exception e) {
      log.error(e.getMessage(),e);
    }
  }

  public void setSmtpHost(String smtpHost) {
    this.smtpHost = smtpHost;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public void setSmtpAuth(String smtpAuth) {
    this.smtpAuth = smtpAuth;
  }
}

扫码或长按识别访问