实现短信验证码登录

文章目录

  • 在开发短信验证码接口
    • 验证码实体SmsCode
    • 手机验证码发送接口
    • 手机验证码生成接口
    • 不拦截短信验证码路径
    • 登录页面
    • 测试
    • 重构
      • 校验码处理接口 ValidateCodeProcessor,封装不同校验码的处理逻辑
      • 抽象实现 AbstractValidateCodeProcessor
      • 两个子类分别实现发送功能 ImageCodeProcessor SmsCodeProcessor
      • ValidateCodeController 简化
  • 短信登录开发

在开发短信验证码接口

在之前图片验证码的基础上开发短信验证码

验证码实体SmsCode

  1. 短信验证码和图片验证码就差一个图片属性,直接把ImageCode拿来改成SmsCode并去掉 private BufferedImage image; 属性就行

  2. 因此可以使ImageCode继承SmsCode

  3. 最后把SmsCode名字改为ValidateCode比较好

  4. 验证码生成器ValidateCodeGenerator的返回值从ImageCode改为ValidateCode

手机验证码发送接口

每个人的短信验证码发送服务商都不同,应该让他们自己实现

SmsCodeSender

public interface SmsCodeSender {void send(String mobile,String code);}

SmsCodeSender默认实现DefaultSmsCodeSender

public class DefaultSmsCodeSender implements SmsCodeSender {@Overridepublic void send(String mobile, String code) {System.out.println("向手机发送短信验证码"+mobile+"---"+code);}
}

默认实现应该是让使用者覆盖掉的 同图片验证码生成器接口一样
配置如下
ValidateCodeBeanConfig

@Configuration
public class ValidateCodeBeanConfig {@Autowiredprivate SecurityProperties securityProperties;@Bean@ConditionalOnMissingBean(name = "imageCodeGenerator")public ValidateCodeGenerator imageCodeGenerator() { //方法的名字就是spring容器中bean的名字ImageCodeGenerator codeGenerator = new ImageCodeGenerator();codeGenerator.setSecurityProperties(securityProperties);return codeGenerator;}@Bean
//	@ConditionalOnMissingBean(name = "smsCodeSender")@ConditionalOnMissingBean(SmsCodeSender.class)//当容器中找到了SmsCodeSender的实现就不会再用此实现beanpublic SmsCodeSender smsCodeSender() { //方法的名字就是spring容器中bean的名字return new DefaultSmsCodeSender();}}

手机验证码生成接口

类似于图像验证码生成接口

ValidateCodeController

@Autowiredprivate ValidateCodeGenerator smsCodeGenerator;//注入手机验证码创建接口@Autowiredprivate SmsCodeSender smsCodeSender; //注入手机验证码发送器@RequestMapping("/code/sms")private void createSms(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletRequestBindingException {//1根据请求中的随机数生成图片ValidateCode smsCode = smsCodeGenerator.generate(new ServletWebRequest(request));//2将随机数放到session中sessionStrategy.setAttribute(new ServletWebRequest(request),SESSION_KEY,smsCode);//3、这块应该由短信服务商将我们的短信发送出去,我们需要封装一个短信验证码发送的接口String mobile = ServletRequestUtils.getRequiredStringParameter(request,"mobile");smsCodeSender.send(mobile,smsCode.getCode());}

SmsCodeGenerator

手机验证码的长度和过期时间做成可配置的属性,具体方法和图片验证码的创建相似,这里就不介绍了

@Component("smsCodeGenerator")
public class SmsCodeGenerator implements ValidateCodeGenerator {@Autowiredprivate SecurityProperties securityProperties;/** (non-Javadoc)* * @see* com.imooc.security.core.validate.code.ValidateCodeGenerator#generate(org.* springframework.web.context.request.ServletWebRequest)*/@Overridepublic ValidateCode generate(ServletWebRequest request) {String code = RandomStringUtils.randomNumeric(securityProperties.getCode().getSms().getLength());return new ValidateCode(code, securityProperties.getCode().getSms().getExpireIn());}public SecurityProperties getSecurityProperties() {return securityProperties;}public void setSecurityProperties(SecurityProperties securityProperties) {this.securityProperties = securityProperties;}}

不拦截短信验证码路径

BrowserSecurityConfig

···························.and().authorizeRequests() //对请求授权
//                .antMatchers("/signIn.html","/code/image").permitAll() //加一个匹配器 对匹配的路径不进行身份认证.antMatchers(securityProperties.getBrowser().getLoginPage(),"/code/*").permitAll() //加一个匹配器 对匹配的路径不进行身份认证···························

登录页面

在这里插入图片描述

<h3>短信登录</h3>
<form action="/authentication/mobile" method="post"><table><tr><td>手机号:</td><td><input type="text" name="mobile" value="13012345678"></td></tr><tr><td>短信验证码:</td><td><input type="text" name="smsCode"><a href="/code/sms?mobile=13012345678">发送验证码</a></td></tr><tr><td colspan="2"><button type="submit">登录</button></td></tr></table>
</form>

测试

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

重构

现在我们的验证码生成器有两个实现的接口

@Autowired
private ValidateCodeGenerator imageCodeGenerator;@Autowired
private ValidateCodeGenerator smsCodeGenerator;

使用模板方法重构,重构后的结构如下
在这里插入图片描述

校验码处理接口 ValidateCodeProcessor,封装不同校验码的处理逻辑

/*** 校验码处理器,封装不同校验码的处理逻辑* * @author zhailiang**/
public interface ValidateCodeProcessor {/*** 验证码放入session时的前缀*/String SESSION_KEY_PREFIX = "SESSION_KEY_FOR_CODE_";/*** 创建校验码* * @param request* @throws Exception* ServletWebRequest spring提供的一个工具类  可以封装请求和响应*/void create(ServletWebRequest request) throws Exception;}

抽象实现 AbstractValidateCodeProcessor

public abstract class AbstractValidateCodeProcessor<C extends ValidateCode> implements ValidateCodeProcessor {/*** 操作session的工具类*/private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();/*** 收集系统中所有的 {@link ValidateCodeGenerator} 接口的实现。** 这个map的注入* spring启动的时候,会查找map的value接口ValidateCodeGenerator的所有实现bean,* 并把这个bean为value,bean的名称为key存入map中** 这种行为叫依赖搜索*/@Autowiredprivate Map<String, ValidateCodeGenerator> validateCodeGenerators;/** (non-Javadoc)* * @see* com.whale.security.core.validate.code.ValidateCodeProcessor#create(org.* springframework.web.context.request.ServletWebRequest)*/@Overridepublic void create(ServletWebRequest request) throws Exception {C validateCode = generate(request);//生成save(request, validateCode);//保存send(request, validateCode);//发送 这是一个抽象方法 需要子类去实现}/*** 生成校验码* * @param request* @return*/@SuppressWarnings("unchecked")private C generate(ServletWebRequest request) {String type = getProcessorType(request);String generatorName = type + "CodeGenerator";ValidateCodeGenerator validateCodeGenerator = validateCodeGenerators.get(generatorName);if (validateCodeGenerator == null) {throw new ValidateCodeException("验证码生成器" + generatorName + "不存在");}return (C) validateCodeGenerator.generate(request);}/*** 保存校验码** @param request* @param validateCode*/private void save(ServletWebRequest request, C validateCode) {sessionStrategy.setAttribute(request, getSessionKey(request), validateCode);}/*** 构建验证码放入session时的key** @param request* @return*/private String getSessionKey(ServletWebRequest request) {return SESSION_KEY_PREFIX + getProcessorType(request);}/*** 发送校验码,由子类实现* 它的抽象方法 send由具体的子类实现* * @param request* @param validateCode* @throws Exception*/protected abstract void send(ServletWebRequest request, C validateCode) throws Exception;/*** 根据请求的url获取校验码的类型* @param request* @return*/private String getProcessorType(ServletWebRequest request){String type = StringUtils.substringAfter(request.getRequest().getRequestURI(), "/code/");return type;}
}

两个子类分别实现发送功能 ImageCodeProcessor SmsCodeProcessor

ImageCodeProcessor

@Component("imageCodeProcessor")
public class ImageCodeProcessor extends AbstractValidateCodeProcessor<ImageCode> {/*** 发送图形验证码,将其写到响应中*/@Overrideprotected void send(ServletWebRequest request, ImageCode imageCode) throws Exception {ImageIO.write(imageCode.getImage(), "JPEG", request.getResponse().getOutputStream());}}

SmsCodeProcessor

@Component("smsCodeProcessor")
public class SmsCodeProcessor extends AbstractValidateCodeProcessor<ValidateCode> {/*** 短信验证码发送器*/@Autowiredprivate SmsCodeSender smsCodeSender;@Overrideprotected void send(ServletWebRequest request, ValidateCode validateCode) throws Exception {
//		String mobile= ServletRequestUtils.getStringParameter((ServletRequest) request, "mobile");
//		String mobile= ServletRequestUtils.getRequiredStringParameter((ServletRequest)request,"mobile");String mobile= ServletRequestUtils.getRequiredStringParameter(request.getRequest(),"mobile");smsCodeSender.send(mobile, validateCode.getCode());}}

ValidateCodeController 简化

@RestController
public class ValidateCodeController implements Serializable {public static  final  String SESSION_KEY ="SESSION_KEY_IMAGE_CODE";//key@Autowiredprivate Map<String, ValidateCodeProcessor> validateCodeProcessors;/*** 创建验证码,根据验证码类型不同,调用不同的 {@link ValidateCodeProcessor}接口实现** @param request* @param response* @param type* @throws Exception*/@GetMapping("/code/{type}")public void createCode(HttpServletRequest request, HttpServletResponse response, @PathVariable String type)throws Exception {validateCodeProcessors.get(type+"CodeProcessor").create(new ServletWebRequest(request,response));}}

短信登录开发

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

SmsCodeAuthenticationToken

public class SmsCodeAuthenticationToken extends AbstractAuthenticationToken {private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;// ~ Instance fields// ================================================================================================private final Object principal;// ~ Constructors// ===================================================================================================/*** This constructor can be safely used by any code that wishes to create a* <code>UsernamePasswordAuthenticationToken</code>, as the {@link #isAuthenticated()}* will return <code>false</code>.**/public SmsCodeAuthenticationToken(String mobile) {super(null);this.principal = mobile;setAuthenticated(false);}/*** This constructor should only be used by <code>AuthenticationManager</code> or* <code>AuthenticationProvider</code> implementations that are satisfied with* producing a trusted (i.e. {@link #isAuthenticated()} = <code>true</code>)* authentication token.** @param principal* @param* @param authorities*/public SmsCodeAuthenticationToken(Object principal,Collection<? extends GrantedAuthority> authorities) {super(authorities);this.principal = principal;super.setAuthenticated(true); // must use super, as we override}// ~ Methods// ========================================================================================================@Overridepublic Object getCredentials() {return null;}@Overridepublic Object getPrincipal() {return this.principal;}@Overridepublic void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {if (isAuthenticated) {throw new IllegalArgumentException("Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");}super.setAuthenticated(false);}@Overridepublic void eraseCredentials() {super.eraseCredentials();}
}

SmsCodeAuthenticationProvider

public class SmsCodeAuthenticationProvider implements AuthenticationProvider {private UserDetailsService userDetailsService;/** (non-Javadoc)* * @see org.springframework.security.authentication.AuthenticationProvider#* authenticate(org.springframework.security.core.Authentication)*/@Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {SmsCodeAuthenticationToken authenticationToken = (SmsCodeAuthenticationToken) authentication;String principal = (String) authenticationToken.getPrincipal();//token中的手机号UserDetails user = userDetailsService.loadUserByUsername(principal);//根据手机号拿到对应的UserDetailsif (user == null) {throw new InternalAuthenticationServiceException("无法获取用户信息");}SmsCodeAuthenticationToken authenticationResult = new SmsCodeAuthenticationToken(user, user.getAuthorities());authenticationResult.setDetails(authenticationToken.getDetails());return authenticationResult;}/** (non-Javadoc)* * @see org.springframework.security.authentication.AuthenticationProvider#* supports(java.lang.Class)** AuthenticationManager 判断参数authentication是不是对应的token*/@Overridepublic boolean supports(Class<?> authentication) {return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication);}public UserDetailsService getUserDetailsService() {return userDetailsService;}public void setUserDetailsService(UserDetailsService userDetailsService) {this.userDetailsService = userDetailsService;}}

SmsCodeAuthenticationFilter

public class SmsCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {// ~ Static fields/initializers// =====================================================================================private static String WHALE_FROM_MOBILE_KEY="mobile";private String mobileParameter = WHALE_FROM_MOBILE_KEY;private boolean postOnly = true;//当前处理器是否处理post请求// ~ Constructors// ===================================================================================================/*** 当前过滤器处理的请求是什么* 一个路径匹配器  手机表单登录的一个请求*/public SmsCodeAuthenticationFilter() {super(new AntPathRequestMatcher("/authentication/mobile", "POST"));}// ~ Methods// ========================================================================================================@Overridepublic Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)throws AuthenticationException {if (postOnly && !request.getMethod().equals("POST")) {//当前请求如果不是post请求则抛出异常throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());}String mobile = obtainMobile(request);//从请求中获取mobile参数if (mobile == null) {mobile = "";}mobile = mobile.trim();//实例化tokenSmsCodeAuthenticationToken authRequest = new SmsCodeAuthenticationToken(mobile);// Allow subclasses to set the "details" propertysetDetails(request, authRequest);//使用AuthenticationManager 调用 tokenreturn this.getAuthenticationManager().authenticate(authRequest);}/*** 获取手机号*/protected String obtainMobile(HttpServletRequest request) {return request.getParameter(mobileParameter);}/*** Provided so that subclasses may configure what is put into the* authentication request's details property.** @param request*            that an authentication request is being created for* @param authRequest*            the authentication request object that should have its details*            set*/protected void setDetails(HttpServletRequest request, SmsCodeAuthenticationToken authRequest) {authRequest.setDetails(authenticationDetailsSource.buildDetails(request));}/*** Sets the parameter name which will be used to obtain the username from* the login request.** @param usernameParameter*            the parameter name. Defaults to "username".*/public void setMobileParameter(String usernameParameter) {Assert.hasText(usernameParameter, "Username parameter must not be empty or null");this.mobileParameter = usernameParameter;}/*** Defines whether only HTTP POST requests will be allowed by this filter.* If set to true, and an authentication request is received which is not a* POST request, an exception will be raised immediately and authentication* will not be attempted. The <tt>unsuccessfulAuthentication()</tt> method* will be called as if handling a failed authentication.* <p>* Defaults to <tt>true</tt> but may be overridden by subclasses.*/public void setPostOnly(boolean postOnly) {this.postOnly = postOnly;}public final String getMobileParameter() {return mobileParameter;}}

SmsCodeAuthenticationSecurityConfig

@Component
public class SmsCodeAuthenticationSecurityConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {@Autowiredprivate AuthenticationSuccessHandler whaleAuthenticationSuccessHandler;@Autowiredprivate AuthenticationFailureHandler whaleAuthenticationFailureHandler;@Qualifier("myUserDetailsService")@Autowiredprivate UserDetailsService userDetailsService;@Overridepublic void configure(HttpSecurity http) throws Exception {SmsCodeAuthenticationFilter smsCodeAuthenticationFilter = new SmsCodeAuthenticationFilter();smsCodeAuthenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));smsCodeAuthenticationFilter.setAuthenticationSuccessHandler(whaleAuthenticationSuccessHandler);smsCodeAuthenticationFilter.setAuthenticationFailureHandler(whaleAuthenticationFailureHandler);SmsCodeAuthenticationProvider smsCodeAuthenticationProvider = new SmsCodeAuthenticationProvider();smsCodeAuthenticationProvider.setUserDetailsService(userDetailsService);http.authenticationProvider(smsCodeAuthenticationProvider).addFilterAfter(smsCodeAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);}}

SmsCodeFilter

同ImageCodeFilter

校验短信验证码并登录
重构代码

BrowserSecurityConfig

同图片验证码过滤器一样
添加短信验证码过滤器
在这里插入图片描述
添加配置
在这里插入图片描述

测试

ok

重构

在这里插入图片描述
1两个验证码的过滤器合并为一个
2config配置整合
3重复字符串整合SecurityConstants

项目地址
https://github.com/whaleluo/securitydemo.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/8372.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android实现登录系统(二)--SMS短信验证登录

&#xff33;&#xff2d;&#xff33;短信验证登录&#xff0c;大部分提供的这种服务都是要收费的&#xff0c; 但是&#xff2d;&#xff4f;&#xff42;网站提供的并不收费&#xff0c;它是通过验证码的格式收费这样的服务盈利的&#xff0c; 也就是说使用他们的&#xf…

Android入门:利用SmsManager发送短信

我们可以通过Intent调用发送短信的服务&#xff0c;但是也可以通过SmsManager发送&#xff1b; 一、为何需要自己开发短信发送器 虽然在Android系统中已经存在发送短信的应用&#xff0c;但是如果我们在开发其他应用时需要集成发送短信功能&#xff0c;则很方便。 二、开发短信…

难顶!ChatGPT又双叒大面积封号了...

编辑&#xff1a;桃子 【新智元导读】ChatGPT大面积封号ing... ChatGPT又双叒开始大面积封号了... 从昨天开始&#xff0c;许多童鞋纷纷表示&#xff0c;自己的ChatGPT plus账号被封了。 许多人收到了一封来自OpenAI的邮件&#xff0c;文中称由于账号存在可疑行为&#xff0c;…

ChatGPT突遭大规模封号,一场网安强震即将爆发!

前言 ChatGPT狂飙出圈&#xff0c;推出仅5天&#xff0c;用户就超过100万&#xff0c;上线两个月&#xff0c;全球活跃用户就已破1亿。 然而就在这两天又传来劲爆消息&#xff1a;ChatGPT正在悄无声息地大规模封号&#xff01;很多人得知消息后登录就发现自己的账号已经不在。…

ChatGPT全球大封号!数10万企业停摆:第一批玩AI的人,被AI给玩了

观点| Mr.K 主笔| Wendy.L 编辑| Emma 来源| 技术领导力(ID&#xff1a;jishulingdaoli) 3月31日&#xff0c;Open AI就开始无征兆的进行全球大封号&#xff0c;其中亚洲是重灾区&#xff0c;官方没有给出任何声明&#xff0c;具体原因不得而知。并且暂停了这些地区新账号的…

突发!因为这个原因,ChatGPT又双叒大面积封号了...

来源 | 新智源 ID | AI-era ChatGPT又双叒开始大面积封号了... 从昨天开始&#xff0c;许多童鞋纷纷表示&#xff0c;自己的ChatGPT plus账号被封了。 许多人收到了一封来自OpenAI的邮件&#xff0c;文中称由于账号存在可疑行为&#xff0c;为了保障平台安全&#xff0c;才这么…

【产业互联网周报】华为宣布实现MetaERP研发和替换;微软为ChatGPT自研AI芯片;...

关注ITValue&#xff0c;看企业级最新鲜、最价值报道&#xff01; 钉钉、文心一言、WPS等接入大模型&#xff1b;火山引擎推出大模型训练平台及自研DPU&#xff1b;谷歌合并旗下两大人工智能部门Brain和DeepMind&#xff0c;加速研究力战ChatGPT……又是为AIGC疯狂的一周 【产业…

顶级研究机构发布《ChatGPT 全产业研究报告》 120页PDF 打包下载

ChatGPT是时下最火的话题&#xff0c;国内多家顶级研究机构&#xff0c;对ChatGPT做了全方面的研究。为了方便大家学习&#xff0c;小编收集了最新的13份共120页的学习资料&#xff0c;截图如下&#xff1a; 这些资料来自网络&#xff0c;版权归属各研究机构&#xff0c;感谢以…

从大模型走向小模型,谁将是ChatGPT布局to B行业的大赢家?

ChatGPT淘金热 当前&#xff0c;爆发了ChatGPT热潮&#xff0c;吸引众多科技企业陆续加入其中。这与当年美国西部加利福尼亚的淘金热何其相似。 历史总会惊人的相似&#xff0c;ChatGPT聊天机器人好比一座数字化时代的金矿。全世界科技淘金人蜂拥而至&#xff0c;从潮起到潮落…

如何实现chatgpt的打字机效果

点击↑上方↑蓝色“编了个程”关注我~ 这是Yasin的第 88 篇原创文章 打字机效果 最近在搭建chat gpt代理的时候&#xff0c;发现自己的配置虽然能够调通接口&#xff0c;返回数据&#xff0c;但是结果是一次性显示出来的&#xff0c;不像之前的chat gpt的官网demo那样实现了打字…

如何使用ChatGPT提升自己的“码”力?

如何使用chatGPT提升自己的"码"力? 代码评审(CodeReview)代码优化代码释义提供解决方案代码生成设计模式和架构建议学习新知识总结 ChatGPT是什么&#xff0c;我就不用再多介绍了吧&#xff01;相信大家已经看到了它在文本领域所展现出来的实力&#xff0c;虽然目前…

云孚快写:自动生成多级目录,一键生成万字长文

1.产品简介 云孚快写是云孚科技自主研发的一款智能写作产品&#xff0c;基于大模型技术打造&#xff0c;针对长文写作场景深度优化&#xff0c;可根据文章标题一键生成目录&#xff0c;再根据目录一键生成正文&#xff0c;文章字数无上限&#xff0c;可极大提升用户的长文写作…

低调且强大--iVX低代码平台

iVX目录 前言一、低代码那么多 为什么选择iVX&#xff1f;二、“拼”出来的低代码平台&#xff0c;真的好用吗&#xff1f;三、iVX与其他低代码有啥可比性&#xff1f; 前言 首先我们应该明白自动编程突破可能是&#xff1a;领域内Mini LLM 现在的思路都是搞LLM&#xff0c;几乎…

多方合作时,系统间的交互是怎么做的?

大家好&#xff01;我是sum墨&#xff0c;一个一线的底层码农&#xff0c;平时喜欢研究和思考一些技术相关的问题并整理成文&#xff0c;限于本人水平&#xff0c;如果文章和代码有表述不当之处&#xff0c;还请不吝赐教。 以下是正文&#xff01; 文章背景 我们最近做了很多…

你真正了解低代码么?(国内低代码平台状况分析)

■ 写在前面■ 低代码产品如何分类&#xff0c;90% 的人都没有搞清楚■ 低代码平台如何比较&#xff1f;Point 在哪儿&#xff1f;一个比喻大家全听懂■ “拼”出来的低代码平台&#xff0c;真的好用吗&#xff1f;■ 推荐一款 C 端低代码产品 ■ 写在前面 都说技术是生产力&a…

【AI实战】给类ChatGPT的大语言模型外挂私有知识库

【AI实战】给类ChatGPT的大语言模型外挂私有知识库 原理准备环境代码下载 chatglm-6b 模型权重文件下载 Embedding 模型 GanymedeNil/text2vec-large-chinese安装依赖库我的计算资源 外挂知识库开启服务外挂知识库 测试参考 本文使用 langChain 来给大语言模型 ChatGLM-6B 外挂…

一块GPU搞定ChatGPT;ML系统入坑指南;理解GPU底层架构

1. 跑ChatGPT体量模型&#xff0c;从此只需一块GPU 在发展技术&#xff0c;让大模型掌握更多能力的同时&#xff0c;也有人在尝试降低AI所需的算力资源。最近&#xff0c;一种名为FlexGen的技术因为「一块RTX 3090跑ChatGPT体量模型」而获得了人们的关注。 虽然FlexGen加速后的…

谷歌研究科学家:ChatGPT秘密武器的演进与局限

来源&#xff5c;TalkRL OneFlow编译 翻译&#xff5c;徐佳渝、贾川 同样是基于GPT预训练模型&#xff0c;为什么ChatGPT的效果要远远超出GPT-3等前几代模型&#xff1f;答案已经揭晓&#xff0c;成就ChatGPT的秘密武器在于RLHF&#xff0c;也就是人类反馈的强化学习。 在预训…

用ChatGPT搞定K8s!

Kubernetes&#xff08;K8s&#xff09;非常火&#xff0c;但被人诟病最多的还是其复杂性&#xff0c;并且不管是在云中还是本地&#xff0c;都没有很好的集群故障排除的方法。因此&#xff0c;尽管K8s的采用率持续增长&#xff0c;但许多开发人员和运维团队对这项较新的技术感…

任正非:ChatGPT对我们的机会是什么,内部讲话实录!

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 我新建了人工智能中文站https://ai.weoknow.com 每天给大家更新可用的国内可用chatGPT资源 为感谢全国火花奖获奖者对于产业界及科学界做出的重大贡献&#xff0c;华为组织了与部分获奖老师与专家的座谈会。座谈会上&…