当前位置: 首页 > news >正文

php在网站开发中的应用织梦大气企业网站模板(扁平化风格)

php在网站开发中的应用,织梦大气企业网站模板(扁平化风格),什么是网络营销策略,网站排名优化快速大技术Nacos做注册中心把新建的微服务注册到Nacos上去两个步骤 在配置文件中配置应用名称、nacos的发现注册ip地址#xff0c;端口号在启动类上用EnableDiscoveryClient注解开启注册功能使用Redis存验证码信息加入依赖配置地址和端口号即可直接注入StringRedisTemplate模板类用…大技术Nacos做注册中心把新建的微服务注册到Nacos上去两个步骤 在配置文件中配置应用名称、nacos的发现注册ip地址端口号在启动类上用EnableDiscoveryClient注解开启注册功能使用Redis存验证码信息加入依赖配置地址和端口号即可直接注入StringRedisTemplate模板类用就是使用如下//根据key获取redis中的值String redisCode redisTemplate.opsForValue().get(redis中的key值);//存值到Redis中redisTemplate.opsForValue().set(key值,value值过期时间, 过期单位TimeUnit.MINUTES);使用gitee作社交登录OAuth2.0亮点1这里由于微博开发者权限申请太慢了就使用gitee来实现社交登录社交登录的步骤1前端调用第三方应用作为社交登录这个跟以往的模式不一样以往是前段直接给后端发送请求然后后端处理请求这个是先调用第三方应用作为社交登录也就是先跳转到gitee的登录授权页面然后用户登录自己的gitee账号密码进行授权授权成功后会跳转到指定的应用回调地址然后在后端来处理这个应用回调地址的请求gitee开发者后台管理链接https://gitee.com/oauth/applications/16285调用gitee第三方登录的url地址a hrefhttps://gitee.com/oauth/authorize?client_id自己应用的Client IDredirect_uri自己应用的成功回调地址response_typecodestate1lia hrefhttps://gitee.com/oauth/authorize?client_id32459f971ce6d89cfb9f70899525455d0653cb804f16b38a304e3447dc97d673redirect_urihttp://auth.saodaimall.com/callbackresponse_typecodestate1img stylewidth: 50px;height: 18px;margin-top: 35px; src/static/login/JD_img/gitee.png//a /li2社交服务OAuth2Controller来处理应用回调地址/callback请求分流程其实就只有三行代码是要自己配置的OAuth2Controller的gitee的42-44行其他的基本上是固定的1封装AccessTokenDTO对象然后发给码云服务器如果AccessTokenDTO对象正确的话就返回一个access_token通行令牌其实准确来说是用户授权后会返回一个code然后把code和其他一些信息封装成AccessTokenDTO对象去找码云服务器获取到一个access_token通行令牌最后通过这个access_token通行令牌去找码云服务器要这个用户在gitee上公开的资料信息2获取到了access_token通行令牌去找码云服务器取该用户的公开信息并且转为通用gitee社交登录GiteeUser对象3远程调用会员服务来进行社交登录package com.saodai.saodaimall.auth.controller;import com.alibaba.fastjson.TypeReference; import com.saodai.common.utils.R; import com.saodai.common.vo.MemberResponseVo; import com.saodai.saodaimall.auth.component.GitheeProvider; import com.saodai.saodaimall.auth.feign.MemberFeignService; import com.saodai.saodaimall.auth.vo.AccessTokenDTO; import com.saodai.saodaimall.auth.vo.GiteeUser; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam;import javax.servlet.http.HttpSession;import static com.saodai.common.constant.AuthServerConstant.LOGIN_USER;/** * 社交第三方授权登录 **/Slf4j Controller public class OAuth2Controller {Autowiredprivate MemberFeignService memberFeignService;Autowiredprivate AccessTokenDTO accessTokenDTO;Autowiredprivate GitheeProvider githeeProvider;GetMapping(value /callback)// /callback?codee867a1f4575d4a6161e3249423a0403898253bc593e4b031a8771739ee6769f5state1public String gitee(RequestParam(name code) String code,RequestParam(name state) String state, HttpSession session) throws Exception {System.out.println(code);//下面三行代码都是自己应用的值可以在gitee的第三方应用中看到对应的值accessTokenDTO.setClient_id(32459f971ce6d89cfb9f70899525455d0653cb804f16b38a304e3447dc97d673);accessTokenDTO.setClient_secret(f3046c911c03cadcded986062708150d4232af3ca6aef0259e5a0198d2c15ba5);accessTokenDTO.setRedirect_uri(http://auth.saodaimall.com/callback);accessTokenDTO.setCode(code);accessTokenDTO.setState(state);String accessToken githeeProvider.getAccessToken(accessTokenDTO);//2、处理if (!StringUtils.isEmpty(accessToken)) {//获取到了access_token,转为通用gitee社交登录对象GiteeUser giteeUser githeeProvider.getGiteeUser(accessToken);//知道了哪个社交用户//1、当前用户如果是第一次进网站自动注册进来为当前社交用户生成一个会员信息以后这个社交账号就对应指定的会员//登录或者注册这个社交用户//调用远程服务R oauthLogin memberFeignService.oauthLogin(giteeUser);if (oauthLogin.getCode() 0) {MemberResponseVo memberResponseVo oauthLogin.getData(data, new TypeReferenceMemberResponseVo() {});log.info(登录成功用户信息{},memberResponseVo.toString());//1、第一次使用session命令浏览器保存卡号JSESSIONID这个cookie//以后浏览器访问哪个网站就会带上这个网站的cookie//TODO 1、默认发的令牌。当前域解决子域session共享问题//TODO 2、使用JSON的序列化方式来序列化对象到Redis中session.setAttribute(LOGIN_USER,memberResponseVo);//2、登录成功跳回首页return redirect:http://saodaimall.com;} else {return redirect:http://auth.saodaimall.com/login.html;}} else {return redirect:http://auth.saodaimall.com/login.html;}}}package com.saodai.saodaimall.auth.vo;/*** AccessTokenDTO对象封装gitee社交登录令牌*/import org.springframework.stereotype.Component;Component public class AccessTokenDTO {private String client_id;private String client_secret;private String code;private String redirect_uri;private String state;public String getClient_id() {return client_id;}public void setClient_id(String client_id) {this.client_id client_id;}public String getClient_secret() {return client_secret;}public void setClient_secret(String client_secret) {this.client_secret client_secret;}public String getCode() {return code;}public void setCode(String code) {this.code code;}public String getRedirect_uri() {return redirect_uri;}public void setRedirect_uri(String redirect_uri) {this.redirect_uri redirect_uri;}public String getState() {return state;}public void setState(String state) {this.state state;} }package com.saodai.saodaimall.auth.component;import com.alibaba.fastjson.JSON; import com.saodai.saodaimall.auth.vo.AccessTokenDTO; import com.saodai.saodaimall.auth.vo.GiteeUser; import okhttp3.*; import org.springframework.stereotype.Component;import java.io.IOException;/*** 请求码云服务器*/ Component public class GitheeProvider {//发起post请求获取AccessTokenpublic String getAccessToken(AccessTokenDTO accessTokenDTO){MediaType mediaType MediaType.get(application/json; charsetutf-8);OkHttpClient client new OkHttpClient();RequestBody body RequestBody.create(mediaType, JSON.toJSONString(accessTokenDTO));Request request new Request.Builder().url(https://gitee.com/oauth/token?grant_typeauthorization_codecodeaccessTokenDTO.getCode()client_idaccessTokenDTO.getClient_id()redirect_uriaccessTokenDTO.getRedirect_uri()client_secretaccessTokenDTO.getClient_secret()).post(body).build();try (Response response client.newCall(request).execute()) {String string response.body().string();System.out.println(string);String str1 string.split(:)[1];String str2 str1.split(\)[1];return str2;} catch (IOException e) {e.printStackTrace();}return null;}//发起get请求返回GitUser对象public GiteeUser getGiteeUser(String token){OkHttpClient client new OkHttpClient();Request request new Request.Builder().url(https://gitee.com/api/v5/user?access_tokentoken).build();try (Response response client.newCall(request).execute()) {String stringresponse.body().string();GiteeUser giteeUser JSON.parseObject(string, GiteeUser.class);return giteeUser;} catch (IOException e) {e.printStackTrace();}return null;} }package com.saodai.saodaimall.auth.vo;import lombok.Data;/*** GiteeUser对象封装社交登录的gitee对象*/ Data public class GiteeUser {//gitee用户名称private String name;//gitee用户idprivate String id;//gitee用户自我介绍private String bio;}3远程调用会员服务来进行社交登录/*** 社交登录* param giteeUser* return* throws Exception*/PostMapping(value /oauth2/login)public R oauthLogin(RequestBody GiteeUser giteeUser) throws Exception {MemberEntity memberEntity memberService.login(giteeUser);if (memberEntity ! null) {return R.ok().setData(memberEntity);} else {return R.error(BizCodeEnum.LOGINACCT_PASSWORD_EXCEPTION.getCode(),BizCodeEnum.LOGINACCT_PASSWORD_EXCEPTION.getMessage());}} /*** 社交登录* param giteeUser* return* throws Exception*/Overridepublic MemberEntity login(GiteeUser giteeUser) throws Exception {//获取gitee用户唯一idString giteeUserId giteeUser.getId();//1、判断当前社交用户是否已经登录过系统MemberEntity memberEntity this.baseMapper.selectOne(new QueryWrapperMemberEntity().eq(social_id, giteeUserId));//这个用户已经注册过if (memberEntity ! null) {return memberEntity;} else {//2、没有查到当前社交用户对应的记录我们就需要注册一个MemberEntity register new MemberEntity();//社交gitee登录的id作为会员idregister.setId(Long.valueOf(giteeUserId));register.setSocialName(giteeUser.getName());register.setUsername(giteeUser.getName());register.setNickname(giteeUser.getName());register.setCreateTime(new Date());register.setSocialBio(giteeUser.getBio());register.setSocialId(giteeUserId);//把用户信息插入到数据库中this.baseMapper.insert(register);return register;}}package com.saodai.saodaimall.member.entity;import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data;import java.io.Serializable; import java.util.Date;/*** 会员*/ Data TableName(ums_member) public class MemberEntity implements Serializable {private static final long serialVersionUID 1L;/*** id*/TableIdprivate Long id;/*** 会员等级id*/private Long levelId;/*** 用户名*/private String username;/*** 密码*/private String password;/*** 昵称*/private String nickname;/*** 手机号码*/private String mobile;/*** 邮箱*/private String email;/*** 头像*/private String header;/*** 性别*/private Integer gender;/*** 生日*/private Date birth;/*** 所在城市*/private String city;/*** 职业*/private String job;/*** 个性签名*/private String sign;/*** 用户来源*/private Integer sourceType;/*** 积分*/private Integer integration;/*** 成长值*/private Integer growth;/*** 启用状态*/private Integer status;/*** 注册时间*/private Date createTime;/*** 社交登录用户的ID*/private String socialId;/*** 社交登录用户的名称*/private String socialName;/*** 社交登录用户的自我介绍*/private String socialBio;}整合SpringSession来解决session不同步不共享的问题亮点2使用SpringSession的目的是来解决分布式session不同步不共享的问题。使用SpringSession可以把session都存在redis中这样就解决了session不同步的问题然后扩大作用域这就解决了session不共享的问题SpringSession不需要显性的操作也就是不需要用StringRedisTemplate类的方法来把session放到redis中去啥都不用干就正常的把数据放到HttpSession中就可由于整合了SpringSession所以放到HttpSession中的数据会自动的放到redis中去由于配置了序列化所以session会被序列化json字符串放到redis中去然后前端某个服务要取这个session的时候也会自动的redis中取注意由于这里使用springsession的用的类型是redis所以这springsession和redis都要一起加入依赖和配置所以session会被存到Redis缓存中1导入依赖!-- 整合springsession 来解决分布式session不同步不共享的问题-- dependencygroupIdorg.springframework.session/groupIdartifactIdspring-session-data-redis/artifactId /dependency !-- 整合redis-- dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId /dependency2在application.properties配置文件里配置springsession#配置springsession spring.session.store-typeredis server.servlet.session.timeout30m #配置redis的ip地址 spring.redis.host192.168.241.1283在config配置中加入springSession配置类package com.saodai.saodaimall.order.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.session.web.http.CookieSerializer; import org.springframework.session.web.http.DefaultCookieSerializer;/** * springSession配置类所有要使用session的服务的session配置要一致 */Configuration public class GulimallSessionConfig {/*** 配置session主要是为了放大session作用域* return*/Beanpublic CookieSerializer cookieSerializer() {DefaultCookieSerializer cookieSerializer new DefaultCookieSerializer();//放大作用域cookieSerializer.setDomainName(saodaimall.com);cookieSerializer.setCookieName(SAODAISESSION);return cookieSerializer;}/*** 配置Session放到redis存储的格式为json其实就是json序列化* return*/Beanpublic RedisSerializerObject springSessionDefaultRedisSerializer() {return new GenericJackson2JsonRedisSerializer();}}4在启动类上添加EnableRedisHttpSession注解package com.saodai.saodaimall.order;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;/*** 订单服务启动类*/ EnableFeignClients EnableRedisHttpSession EnableDiscoveryClient SpringBootApplication public class SaodaimallOrderApplication {public static void main(String[] args) {SpringApplication.run(SaodaimallOrderApplication.class, args);}}SpringSession的原理Spring-Session的实现就是设计一个过滤器SessionRepositoryFilter每当有请求进入时过滤器会首先将ServletRequest 和ServletResponse 这两个对象转换成Spring内部的包装类SessionRepositoryRequestWrapper和SessionRepositoryResponseWrapper对象它使用了一个SessionRepositoryRequestWrapper类接管了Http Session并重写了getSession方法来实现了session的创建和管理工作。将原本需要由web服务器创建会话的过程转交给Spring-Session进行创建本来创建的会话保存在Web服务器内存中通过Spring-Session创建的会话信息可以保存第三方的服务中如redis,mysql等。Web服务器之间通过连接第三方服务来共享数据实现Session共享Order(SessionRepositoryFilter.DEFAULT_ORDER) public class SessionRepositoryFilterS extends Session extends OncePerRequestFilter {Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {request.setAttribute(SESSION_REPOSITORY_ATTR, this.sessionRepository);//使用HttpServletRequest 、HttpServletResponse和servletContext创建一个SessionRepositoryRequestWrapperSessionRepositoryRequestWrapper wrappedRequest new SessionRepositoryRequestWrapper(request, response, this.servletContext);SessionRepositoryResponseWrapper wrappedResponse new SessionRepositoryResponseWrapper(wrappedRequest, response);try {filterChain.doFilter(wrappedRequest, wrappedResponse);}finally {//保存session信息wrappedRequest.commitSession();}} } Overridepublic HttpSessionWrapper getSession(boolean create) {//获取当前Request作用域中代表Session的属性缓存作用避免每次都从sessionRepository获取HttpSessionWrapper currentSession getCurrentSession();if (currentSession ! null) {return currentSession;}//查找客户端中一个叫SESSION的cookie拿到sessionId通过sessionRepository对象根据sessionId去Redis中查找S requestedSession getRequestedSession();//如果从redis中查询到了值if (requestedSession ! null) {//客户端存在sessionId 并且未过期if (getAttribute(INVALID_SESSION_ID_ATTR) null) {requestedSession.setLastAccessedTime(Instant.now());this.requestedSessionIdValid true;currentSession new HttpSessionWrapper(requestedSession, getServletContext());currentSession.setNew(false);//将Session设置到request属性中setCurrentSession(currentSession);return currentSession;}}else {// This is an invalid session id. No need to ask again if// request.getSession is invoked for the duration of this requestif (SESSION_LOGGER.isDebugEnabled()) {SESSION_LOGGER.debug(No session found by id: Caching result for getSession(false) for this HttpServletRequest.);}setAttribute(INVALID_SESSION_ID_ATTR, true);}//不创建Session就直接返回nullif (!create) {return null;}if (SESSION_LOGGER.isDebugEnabled()) {SESSION_LOGGER.debug(A new session was created. To help you troubleshoot where the session was created we provided a StackTrace (this is not an error). You can prevent this from appearing by disabling DEBUG logging for SESSION_LOGGER_NAME,new RuntimeException(For debugging purposes only (not an error)));}//执行到这了说明需要创建新的Session// 通过sessionRepository创建RedisSession这个对象S session SessionRepositoryFilter.this.sessionRepository.createSession();session.setLastAccessedTime(Instant.now());currentSession new HttpSessionWrapper(session, getServletContext());setCurrentSession(currentSession);return currentSession;}// 通过sessionRepository创建RedisSession这个对象Overridepublic RedisSession createSession() {Duration maxInactiveInterval Duration.ofSeconds((this.defaultMaxInactiveInterval ! null)? this.defaultMaxInactiveInterval: MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS);RedisSession session new RedisSession(maxInactiveInterval);session.flushImmediateIfNecessary();return session;}好文参考Spring-Session实现session共享原理及解析_五霸哥的博客-CSDN博客_session共享如何实现小技术使用视图映射器来实现页面跳转传统写法是在控制器里实现自定义一个配置类来实现WebMvcConfigurer接口然后重写addViewControllers方法来增加视图映射器使用配置文件来动态配置属性值这样就可以通过在配置文件里修改对应的值来改变属性值核心注解是ConfigurationPropertiesprefix,Data注解也要加使用Feign远程调用服务添加openFeign依赖并且在启动了通过EnableFeignClients注解开启远程调用端即可用feign远程调用服务定义一个远程调用的接口通过FeignClient注解来指定调用哪个服务把第三方服务控制器的方法签名拿过来即可注意路径一定要写对特别是如果有父路径不要忘了写在需要远程调用的服务器里注入刚写的远程接口然后调用就可例如这里是认证中心调用第三方服务的发生验证码的接口使用异常机制 /*** 会员注册*/Overridepublic void register(MemberUserRegisterVo vo) {MemberEntity memberEntity new MemberEntity();//设置默认等级MemberLevelEntity levelEntity memberLevelDao.getDefaultLevel();memberEntity.setLevelId(levelEntity.getId());//设置其它的默认信息//检查用户名和手机号是否唯一。感知异常异常机制异常机制就是问题就抛出具体异常没问题就继续执行下面的语句checkPhoneUnique(vo.getPhone());checkUserNameUnique(vo.getUserName());memberEntity.setNickname(vo.getUserName());memberEntity.setUsername(vo.getUserName());//密码进行MD5盐值加密盐值加密同一个数据的每次加密结果是不一样的通过match方法来密码校验// 注意这里不能用md5直接加密放数据库因为彩虹表可以破解md5所谓彩虹表就是通过大量的md5数据反向退出md5// 注意MD5是不可逆但是可暴力通过彩虹表破解BCryptPasswordEncoder bCryptPasswordEncoder new BCryptPasswordEncoder();String encode bCryptPasswordEncoder.encode(vo.getPassword());memberEntity.setPassword(encode);memberEntity.setMobile(vo.getPhone());memberEntity.setGender(0);memberEntity.setCreateTime(new Date());//保存数据this.baseMapper.insert(memberEntity);}/*** 检查手机号是否重复的异常机制方法* param phone* throws PhoneException*/Overridepublic void checkPhoneUnique(String phone) throws PhoneException {Long phoneCount this.baseMapper.selectCount(new QueryWrapperMemberEntity().eq(mobile, phone));//usernameCount 0表示手机号已经存在if (phoneCount 0) {throw new PhoneException();}}/*** 检查用户名是否重复的异常机制方法* param userName* throws UsernameException*/Overridepublic void checkUserNameUnique(String userName) throws UsernameException {Long usernameCount this.baseMapper.selectCount(new QueryWrapperMemberEntity().eq(username, userName));//usernameCount 0表示用户名已经存在if (usernameCount 0) {throw new UsernameException();}}上面定义检查用户名和电话号码的异常机制方法的具体实现 /*** 会员注册功能* param vo* return*/PostMapping(value /register)public R register(RequestBody MemberUserRegisterVo vo) {try {memberService.register(vo);} catch (PhoneException e) {//BizCodeEnum.PHONE_EXIST_EXCEPTION存在相同的手机号 15002return R.error(BizCodeEnum.PHONE_EXIST_EXCEPTION.getCode(),BizCodeEnum.PHONE_EXIST_EXCEPTION.getMessage());} catch (UsernameException e) {//BizCodeEnum.USER_EXIST_EXCEPTION商品库存不足 21000return R.error(BizCodeEnum.USER_EXIST_EXCEPTION.getCode(),BizCodeEnum.USER_EXIST_EXCEPTION.getMessage());}return R.ok();}使用异常机制的原因就是希望控制器能够发现并处理异常package com.saodai.saodaimall.member.exception;public class UsernameException extends RuntimeException {public UsernameException() {super(存在相同的用户名);} } package com.saodai.saodaimall.member.exception;public class PhoneException extends RuntimeException {public PhoneException() {super(存在相同的手机号);} }把上面两个单独的异常抽取出来封装成异常类使用MD5盐值加密加密先创建一个加密器BCryptPasswordEncoder然后调用他的encode方法把需要加密的密码放进去就会自动生成一串加密后的值注意同一个密码每次生成的值是不一样的解密从数据库里面拿到加密的数据后调用matches方法就可以匹配两个密码是否一致如果一致那就返回true不一致返回false前面是password是旧密码没加密的密码后面的passwordDb是数据库加密的密码
http://www.w-s-a.com/news/467105/

相关文章:

  • 网站与新媒体建设测评方案163企业邮箱官网入口
  • 怎样做下载网站页面设计参评
  • 哈尔滨住建局网站首页设计制作过程
  • php投资理财企业网站模板网站呼叫中心 建设工期
  • 查数据的权威网站silverlight 做的网站
  • 网站开发外包网站贵阳网站建设 网站制作
  • 官方微网站西安景观设计公司排行
  • 广州学做网站视频代做网站
  • 沈阳公司建站seo课程培训班
  • 杭州做微信网站软件公司网站建设毕业设计中期进度报告
  • 怎么做谷歌这样的网站如何建立一个网站放视频
  • 园区网站建设调研报告北京朝阳区哪里有网站开发
  • 网站角色权限wordpress 优化版
  • 购物网站ppt怎么做网络公司注册多少钱
  • 学做衣服上什么网站好贴吧高级搜索
  • 贵州 跨境电商网站建设做淘宝店铺有哪些好的网站
  • 广州正规网站制作公司网站搭建公司
  • ui设计零基础好学吗珠海网站建设优化推广
  • 网站开发多少费用火车头采集wordpress发布时间
  • 有没有做皮艺的网站教育培训网站建设ppt
  • 建设外贸商城网站制作如何建设景区旅游网站
  • 网站建设服务的具体条件怎么建设一个响应式网站
  • 做flash的网站wordpress设置前台投稿
  • 商务网站开发文档迅雷资源做下载网站
  • 无极磁铁网站如何把地图放到自己做的网站上
  • 青浦赵巷网站建设公司网站开发需求文档
  • 苏州网站建设的公司哪家好无锡网站制作那些
  • 装饰公司网站模板科技成果鉴定机构
  • 给公司做的东西放到私人网站上十堰为企业做网站的单位
  • 手机网站建设价钱手机自己做网站