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

网站做系统叫什么名字吗佛山网站建设有哪些

网站做系统叫什么名字吗,佛山网站建设有哪些,软件定制开发,餐饮o2o 网站建设作者#xff1a;后端小肥肠 创作不易#xff0c;未经允许严禁转载。 姊妹篇#xff1a; 【Spring Security系列】Spring SecurityJWTRedis实现用户认证登录及登出_spring security jwt 退出登录-CSDN博客 1. 前言 欢迎来到【Spring Security系列】#xff01;在当今数字化… 作者后端小肥肠 创作不易未经允许严禁转载。 姊妹篇 【Spring Security系列】Spring SecurityJWTRedis实现用户认证登录及登出_spring security jwt 退出登录-CSDN博客 1. 前言 欢迎来到【Spring Security系列】在当今数字化时代安全是任何应用程序都必须优先考虑的核心问题之一。而在众多安全框架中Spring Security 作为一个功能强大且广泛应用的安全框架为 Java 应用程序提供了全面的身份验证、授权、攻击防护等功能。而随着移动应用的普及小程序作为一种轻量级、跨平台的应用形式其安全性也成为了开发者们关注的焦点。本文将带领您深入探索如何使用 Spring Security 来保护小程序的登录认证旨在为您提供全方位的学习体验和实践指导。 2. 小程序登录涉及SpringSecurity核心组件介绍 如果要在SpringSecurity默认的用户名密码模式登录模式上扩展小程序登录涉及到的核心组件如下 AuthenticationProvider 创建自定义的AuthenticationProvider负责处理从微信开放平台获取的用户信息并进行身份验证。 UserDetailsService 调整UserDetailsService来获取并管理基于微信OpenID的用户信息。 AuthenticationManager 确保您的自定义AuthenticationProvider被正确注册到AuthenticationManager中以便处理小程序登录请求。 SecurityConfigurer 创建一个SecurityConfigurer来配置Spring Security以支持小程序登录并将其添加到Spring Security的配置类中。 Filter 创建一个自定义的过滤器来拦截和处理小程序登录请求提取微信登录凭证并将其传递给您的自定义AuthenticationProvider进行处理。 要扩展Spring Security以支持小程序登录您需要创建自定义的AuthenticationProvider并调整UserDetailsService以处理微信OpenID的用户信息。 3. SpringSecurity集成小程序登录原理 3.1. 小程序登录流程 以下是微信官方文档中小程序登录的流程 由上图可看出小程序登录使用微信提供的登录凭证 code通过微信开放平台的接口获取用户的唯一标识 OpenID 和会话密钥 SessionKey。在集成小程序登录时我们需要将这些凭证传递给后端服务器由后端服务器进行校验和处理最终完成用户的登录认证。 3.2. SpringSecurity集成小程序登录流程梳理 结合SpringSecurity原理在SpringSecurity中集成小程序登录的流程如下 小程序端通过微信登录接口获取登录凭证 code这里取名为loginCode。小程序端通过手机号快速验证组件获取phoneCode。小程序端获取用户昵称nickName和用户头像imageUrl地址。小程序端将登录凭证 loginCode、phoneCode、nickName、imageUrl发送给后端服务器。后端服务器接收到登录凭证 loginCode后调用微信开放平台的接口换取用户的唯一标识 OpenID 和会话密钥 SessionKey。后端服务器根据 OpenID 查询用户信息如果用户不存在则创建新用户如果用户已存在则返回用户信息。后端服务器生成用户的身份认证信息JWT Token返回给小程序端。小程序端存储用户的身份认证信息后续请求携带该信息进行访问控制。 大体流程只是在3.1小程序登录流程上做了细化图我就不画了因为懒。 3.3. 小程序登录接口设计 小程序登录接口如下图所示 由上图所示我们需要传入loginCodephoneCode获取手机号nickName昵称用于登录后展示imageUrl头像用于登录后展示这几个必传参数。 4. 核心代码讲解 4.1. 小程序端获取必要参数 1. 小程序端调用微信登录接口获取用户登录凭证 loginCode。 wx.login({success (res) {if (res.code) {//发起网络请求wx.request({url: https://example.com/onLogin,data: {code: res.code}})} else {console.log(登录失败 res.errMsg)}} }) 2. 获取PhoneCode 3. 获取头像昵称 4.2. 编写WeChatAuthenticationFilter public class WeChatAuthenticationFilter extends AbstractAuthenticationProcessingFilter {private final String loginCode loginCode;private final String phoneCodephoneCode;private final String nickNamenickName;private final String imageUrlimageUrl;public WeChatAuthenticationFilter(String appId, String secret) {super(new AntPathRequestMatcher(/wx/login, POST));}Overridepublic Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {String loginCode obtainLoginCode(request)null?:obtainLoginCode(request).trim();String phoneCodeobtainPhoneCode(request)null?:obtainPhoneCode(request).trim();String nickNameobtainNickName(request)null?:obtainNickName(request).trim();String imageUrlobtainImageUrl(request)null?:obtainImageUrl(request).trim();WechatAuthenticationToken authRequest new WechatAuthenticationToken(loginCode,phoneCode,nickName,imageUrl);return this.getAuthenticationManager().authenticate(authRequest);}protected String obtainLoginCode(HttpServletRequest request) {return request.getParameter(loginCode);}protected String obtainPhoneCode(HttpServletRequest request){return request.getParameter(phoneCode);}protected String obtainNickName(HttpServletRequest request){return request.getParameter(nickName);}protected String obtainImageUrl(HttpServletRequest request){return request.getParameter(imageUrl);} } 以上代码定义了一个名为WeChatAuthenticationFilter的类它继承自AbstractAuthenticationProcessingFilter类用于处理微信登录认证。在构造函数中指定了请求匹配路径为/wx/login请求方法为POST。类中定义了四个常量loginCode、phoneCode、nickName和imageUrl分别表示登录码、手机号码、昵称和头像URL。 在attemptAuthentication方法中首先通过obtainLoginCode、obtainPhoneCode、obtainNickName和obtainImageUrl方法获取请求中的登录码、手机号码、昵称和头像URL并进行了空值处理。然后将这些信息封装到WechatAuthenticationToken对象中并通过getAuthenticationManager().authenticate方法进行认证。 4.3. 编写WeChatAuthenticationProvider Slf4j public class WeChatAuthenticationProvider implements AuthenticationProvider {private final WechatConfig wechatConfig;private RestTemplate restTemplate;private final WeChatService weChatService;private final ISysUserAuthService sysUserAuthService;public WeChatAuthenticationProvider(WechatConfig wechatConfig, WeChatService weChatService,ISysUserAuthService sysUserAuthService) {this.wechatConfig wechatConfig;this.weChatService weChatService;this.sysUserAuthServicesysUserAuthService;}Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {WechatAuthenticationToken wechatAuthenticationToken (WechatAuthenticationToken) authentication;String loginCode wechatAuthenticationToken.getPrincipal().toString();log.info(loginCode is {},loginCode);String phoneCodewechatAuthenticationToken.getPhoneCode().toString();log.info(phoneCode is {},phoneCode);String nickNamewechatAuthenticationToken.getNickName().toString();log.info(nickName is {},nickName);String imageUrlwechatAuthenticationToken.getImageUrl().toString();log.info(imageUrl is {},imageUrl);restTemplatenew RestTemplate();//获取openIdJwtUser jwtUsernull;String url https://api.weixin.qq.com/sns/jscode2session?appid{appid}secret{secret}js_code{code}grant_typeauthorization_code;MapString, String requestMap new HashMap();requestMap.put(appid, wechatConfig.getAppid());requestMap.put(secret, wechatConfig.getSecret());requestMap.put(code, loginCode);ResponseEntityString responseEntity restTemplate.getForEntity(url, String.class,requestMap);JSONObject jsonObject JSONObject.parseObject(responseEntity.getBody());log.info(JSONObject.toJSONString(jsonObject));String openIdjsonObject.getString(openid);if(StringUtils.isBlank(openId)) {throw new BadCredentialsException(weChat get openId error);}if(sysUserAuthService.getUserAuthCountByIdentifier(openId)0){jwtUser (JwtUser) weChatService.getUserByOpenId(openId);if(!jwtUser.isEnabled()){throw new BadCredentialsException(用户已失效);}return getauthenticationToken(jwtUser,jwtUser.getAuthorities());}//获取手机号第一步获取accessTokenString accessTokenUrlhttps://api.weixin.qq.com/cgi-bin/token?grant_typeclient_credentialappid{appid}secret{secret};MapString, String accessTokenRequestMap new HashMap();accessTokenRequestMap.put(appid, wechatConfig.getAppid());accessTokenRequestMap.put(secret, wechatConfig.getSecret());ResponseEntityString accessTokenResponseEntity restTemplate.getForEntity(accessTokenUrl, String.class,accessTokenRequestMap);JSONObject accessTokenJsonObject JSONObject.parseObject(accessTokenResponseEntity.getBody());log.info(JSONObject.toJSONString(accessTokenJsonObject));String accessTokenaccessTokenJsonObject.getString(access_token);if(StringUtils.isBlank(accessToken)) {throw new BadCredentialsException(weChat get accessToken error);}//获取手机号第二部远程请求获取手机号String pohoneUrlhttps://api.weixin.qq.com/wxa/business/getuserphonenumber?access_tokenaccessToken;JSONObject phoneJsonnew JSONObject();phoneJson.put(code,phoneCode);String resPhoneStr RestTemplateUtil.postForJson(pohoneUrl,phoneJson,restTemplate);log.info(resPhoneStr);JSONObject resPhonJson JSON.parseObject(resPhoneStr);JSONObject phoneInforesPhonJson.getJSONObject(phone_info);String mobilephoneInfo.getString(phoneNumber);if(StringUtils.isBlank(mobile)){throw new BadCredentialsException(Wechat get mobile error);}jwtUser (JwtUser) weChatService.getUserByMobile(mobile,nickName,imageUrl);sysUserAuthService.saveUserAuth(new AddUserAuthReq(jwtUser.getUid(),wechat,openId));return getauthenticationToken(jwtUser,jwtUser.getAuthorities());}Overridepublic boolean supports(Class? authentication) {return WechatAuthenticationToken.class.isAssignableFrom(authentication);}public WechatAuthenticationToken getauthenticationToken(Object principal, Collection? extends GrantedAuthority authorities){WechatAuthenticationToken authenticationTokennew WechatAuthenticationToken(principal,authorities);LinkedHashMapObject, Object linkedHashMap new LinkedHashMap();linkedHashMap.put(principal, authenticationToken.getPrincipal());authenticationToken.setDetails(linkedHashMap);return authenticationToken;} }上述代码是一个自定义的认证提供者类名为WeChatAuthenticationProvider。其主要功能是处理微信登录认证。在authenticate方法中首先从传入的Authentication对象中提取出微信登录所需的参数包括登录码、手机号码、昵称和头像URL。然后通过RestTemplate发送HTTP请求到微信API获取用户的openId以验证用户身份。若成功获取openId则检查系统中是否存在该用户的认证信息若存在则直接返回认证token若不存在则继续获取用户的手机号并根据手机号获取用户信息并保存用户认证信息。最后返回经过认证的token。 4.4. 编写WechatAuthenticationToken public class WechatAuthenticationToken extends AbstractAuthenticationToken {private final Object principal;private Object phoneCode;private Object nickName;private Object imageUrl;public WechatAuthenticationToken(String loginCode,String phoneCode,String nickName,String imageUrl) {super(null);this.principal loginCode;this.phoneCodephoneCode;this.nickNamenickName;this.imageUrlimageUrl;setAuthenticated(false);}public WechatAuthenticationToken(Object principal, Collection? extends GrantedAuthority authorities) {super(authorities);this.principal principal;super.setAuthenticated(true);}Overridepublic Object getCredentials() {return null;}Overridepublic Object getPrincipal() {return this.principal;}public Object getPhoneCode() {return phoneCode;}public Object getNickName() {return nickName;}public Object getImageUrl() {return imageUrl;} }4.5. WechatConfig Data Component ConfigurationProperties(prefixwechat) public class WechatConfig {private String appid;private String secret; } 4.6. 更新WebSecurityConfigurer Configuration public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {AutowiredQualifier(authUserDetailsServiceImpl)private UserDetailsService userDetailsService;Autowiredprivate SecurOncePerRequestFilter securOncePerRequestFilter;Autowiredprivate SecurAuthenticationEntryPoint securAuthenticationEntryPoint;Autowiredprivate SecurAccessDeniedHandler securAccessDeniedHandler;//登录成功处理器Autowiredprivate SecurAuthenticationSuccessHandler securAuthenticationSuccessHandler;Autowiredprivate SecurAuthenticationFailureHandler securAuthenticationFailureHandler;//退出处理器Autowiredprivate SecurLogoutHandler securLogoutHandler;Autowiredprivate SecurLogoutSuccessHandler securLogoutSuccessHandler;AutowiredBCryptPasswordEncoderUtil bCryptPasswordEncoderUtil;Value(${wechat.appid})private String appId;Value(${wechat.secret})private String secret;AutowiredWechatConfig wechatConfig;Autowiredprivate WeChatService weChatService;Autowiredprivate ISysUserAuthService sysUserAuthService;// Autowired // DynamicPermission dynamicPermission;/*** 从容器中取出 AuthenticationManagerBuilder执行方法里面的逻辑之后放回容器** param authenticationManagerBuilder* throws Exception*/Autowiredpublic void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoderUtil);}Overrideprotected void configure(HttpSecurity http) throws Exception {//第1步解决跨域问题。cors 预检请求放行,让Spring security 放行所有preflight requestcors 预检请求http.authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll();//第2步让Security永远不会创建HttpSession它不会使用HttpSession来获取SecurityContexthttp.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().headers().cacheControl();//第3步请求权限配置//放行注册API请求其它任何请求都必须经过身份验证.http.authorizeRequests() // .antMatchers(/**).permitAll().antMatchers(HttpMethod.POST,/sys-user/register).permitAll().antMatchers(HttpMethod.GET,/temp/create,/department/enable-department,/instance/**,/file/download/**).permitAll().antMatchers(/css/**, /js/**, /images/**, /fonts/**,/editor-app/**,/model/**,/editor/**).permitAll().antMatchers(/modeler.html/**).permitAll().antMatchers(/feign/**).permitAll()//ROLE_ADMIN可以操作任何事情.antMatchers(/v2/api-docs, /v2/feign-docs,/swagger-resources/configuration/ui,/swagger-resources,/swagger-resources/configuration/security,/swagger-ui.html, /webjars/**).permitAll().antMatchers(HttpMethod.POST, /user/wx/login).permitAll().anyRequest().authenticated();// .antMatchers(/**).hasAnyAuthority(USER,SUPER_ADMIN,ADMIN);/*由于使用动态资源配置以上代码在数据库中配置如下在sys_backend_api_table中添加一条记录backend_api_id1backend_api_name 所有APIbackend_api_url/**,backend_api_methodGET,POST,PUT,DELETE*///动态加载资源 // .anyRequest().access(dynamicPermission.checkPermisstion(request,authentication));//第4步拦截账号、密码。覆盖 UsernamePasswordAuthenticationFilter过滤器http.addFilterAt(securUsernamePasswordAuthenticationFilter() , UsernamePasswordAuthenticationFilter.class);//第5步拦截token并检测。在 UsernamePasswordAuthenticationFilter 之前添加 JwtAuthenticationTokenFilterhttp.addFilterBefore(securOncePerRequestFilter, UsernamePasswordAuthenticationFilter.class);http.addFilterBefore(weChatAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);//第6步处理异常情况认证失败和权限不足http.exceptionHandling().authenticationEntryPoint(securAuthenticationEntryPoint).accessDeniedHandler(securAccessDeniedHandler);//第7步登录,因为使用前端发送JSON方式进行登录所以登录模式不设置也是可以的。http.formLogin();//第8步退出http.logout().addLogoutHandler(securLogoutHandler).logoutSuccessHandler(securLogoutSuccessHandler);}Beanpublic WeChatAuthenticationFilter weChatAuthenticationFilter() throws Exception {WeChatAuthenticationFilter filter new WeChatAuthenticationFilter(appId, secret);filter.setAuthenticationManager(authenticationManagerBean());filter.setAuthenticationSuccessHandler(securAuthenticationSuccessHandler);filter.setAuthenticationFailureHandler(securAuthenticationFailureHandler);return filter;}/*** 手动注册账号、密码拦截器* return* throws Exception*/BeanSecurUsernamePasswordAuthenticationFilter securUsernamePasswordAuthenticationFilter() throws Exception {SecurUsernamePasswordAuthenticationFilter filter new SecurUsernamePasswordAuthenticationFilter();//成功后处理filter.setAuthenticationSuccessHandler(securAuthenticationSuccessHandler);//失败后处理filter.setAuthenticationFailureHandler(securAuthenticationFailureHandler);filter.setAuthenticationManager(authenticationManagerBean());return filter;}Beanpublic WeChatAuthenticationProvider weChatAuthenticationProvider() {return new WeChatAuthenticationProvider(wechatConfig,weChatService,sysUserAuthService);}Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {// 添加微信登录认证提供者auth.authenticationProvider(weChatAuthenticationProvider());// 添加用户名密码登录认证提供者auth.authenticationProvider(daoAuthenticationProvider());}Beanpublic DaoAuthenticationProvider daoAuthenticationProvider() {DaoAuthenticationProvider provider new DaoAuthenticationProvider();provider.setUserDetailsService(userDetailsService);provider.setPasswordEncoder(new BCryptPasswordEncoder());return provider;} } 说一个容易踩坑的地方在Spring Security中当你配置了自定义的认证提供者如weChatAuthenticationProvider()来处理特定类型的认证如微信登录如果没有同时配置默认的认证提供者如daoAuthenticationProvider()则原有的基于用户名和密码的认证机制不会自动生效。这是因为Spring Security的认证机制是基于一个可配置的AuthenticationManager它管理一个AuthenticationProvider列表这些提供者会依次尝试认证用户提交的Authentication请求。 5. 结语 在本文中以流程讲解和代码实操讲解了如何在已有用户名和密码登录的基础上实现微信小程序登录集成。下期将介绍基于OAuth2框架如何实现小程序登录感兴趣的同学动动你们发财的小手点点关注吧~ 6. 参考链接  开放能力 / 用户信息 / 手机号快速验证组件 (qq.com)
http://www.dnsts.com.cn/news/230120.html

相关文章:

  • 建设银行杭州纪念币预约网站想要学做网站
  • 荷兰网站域名擦边球网站做国内还是国外好
  • 河南企业网站建设公司高清图片素材网站推荐
  • 国外做的比较好的购物网站网站公司怎么做的好处
  • 珠海网站建设解决方案苏州工业园区两学一做教育网站
  • 做跨国婚恋网站赚钱吗网站收录时有时没有
  • 有网站前台如何做后台湖北省建设信息网站
  • 免费的做微博的网站模板wordpress 广告格子
  • 武义建设局网站建筑施工图纸培训班
  • 网站宣传的劣势郑州做网站茂睿科技
  • 广州网站搭建多少钱seo博客
  • 稻壳企业网站模板推广商
  • 企业网站意思页面设计的特点是什么
  • 网站关键词百度自然排名优化厦门网络推广专员
  • 让别人做网站的步骤网站统计开放平台
  • 美团初期是怎么建网站小程序登录入口网页版
  • 山西省建设厅入晋备案网站湘潭做网站出色磐石网络
  • 网站建设运行情况济南响应式网站开发
  • 网站开发属于哪个税收分类事件营销的经典案例
  • 石家庄公司建站wordpress多张页面左右滑动
  • 房屋中介做网站的登陆页面模板
  • 网套加工机器设备关键字优化策略
  • 温州市企业网站制作做自媒体必备的8个网站
  • 福州做网站设计上海网络维护服务公司
  • 全国网站建设公司有多少家全国企业系统网站建设
  • 深圳做网站的网络网站平台做推广方案
  • 安阳网站建设兼职域名注册 万网
  • 网站建设案例基本流程图做兼职的网站有哪些工作
  • 网站建设柚子网络科技官网网站换行代码
  • 室内在线设计网站做内部优惠券网站赚钱吗