shiro授权Shiro+jsp整合Springboot -Shiro
Shiro授权
一、授权
授权
,即访问控制,控制谁能访问哪些资源。主体进行身份认证后需要分配权限方可访问系统的资源,对于某些资源没有权限是无法访问的。
二、关键对象
授权可简单理解为who对what(which)进行How操作:
Who,即主体(Subject)
,主体需要访问系统中的资源。
What,即资源(Resource)
,如系统菜单、页面、按钮、类方法、系统商品信息等。资源包括资源类型
和资源实例
,比如商品信息为资源类型
,类型为t01的商品为资源实例
,编号为001的商品信息也属于资源实例。
How,权限/许可(Permission)
,规定了主体对资源的操作许可,权限离开资源没有意义,如用户查询权限、用户添加权限、某个类方法的调用权限、编号为001用户的修改权限等,通过权限可知主体对哪些资源都有哪些操作许可。
三、授权流程
四、授权方式
-
基于角色的访问控制
-
RBAC基于角色的访问控制(Role-Based Access Control)是以角色为中心进行访问控制
if(subject.hasRole("admin")){//操作什么资源 } 123
-
-
基于资源的访问控制
-
RBAC基于资源的访问控制(Resource-Based Access Control)是以资源为中心进行访问控制
if(subject.isPermission("user:update:01")){ //资源实例//对01用户进行修改 } if(subject.isPermission("user:update:*")){ //资源类型//对01用户进行修改 } 123456
-
五、权限字符串
权限字符串的规则是:资源标识符:操作:资源实例标识符,意思是对哪个资源的哪个实例具有什么操作,“:”是资源/操作/实例的分割符,权限字符串也可以使用*通配符。
例子:
- 用户创建权限:user:create,或user:create:*
- 用户修改实例001的权限:user:update:001
- 用户实例001的所有权限:user : * :001
A:B:C,A通过B来操作C
六、shiro中授权编程实现方式
-
编程式
Subject subject = SecurityUtils.getSubject(); if(subject.hasRole(“admin”)) {//有权限 } else {//无权限 } 123456
-
注解式
@RequiresRoles("admin") public void hello() {//有权限 } 1234
-
标签式
JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成: <shiro:hasRole name="admin"><!— 有权限—> </shiro:hasRole> 注意: Thymeleaf 中使用shiro需要额外集成! 12345
七、开发授权
1.realm的实现
public class CustomMD5Realm extends AuthorizingRealm {//授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {System.out.println("===================");//获取主身份,也就是用户名String primaryPrincipal = (String) principals.getPrimaryPrincipal();System.out.println("身份信息:"+primaryPrincipal);SimpleAuthorizationInfo simpleAuthenticationInfo = new SimpleAuthorizationInfo();//添加角色simpleAuthenticationInfo.addRole("admin");simpleAuthenticationInfo.addStringPermission("user:update:*");simpleAuthenticationInfo.addStringPermission("product:*:*");return simpleAuthenticationInfo;}//认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String username = (String) token.getPrincipal();//用户名if ("achang".equals(username)) {//数据库中存的密码String password = "a5adc0fc389b3236f04d1bf32e127440";//密码,123456的MD5加密String salt = "k2*dw";//盐//参数1:数据库用户名//参数2:数据库密码,md5+salt的密码//参数3:注册时的盐//参数4:realm名return new SimpleAuthenticationInfo(username,password,ByteSource.Util.bytes(salt),this.getName());}return null;}
}
2.授权
public class TestAuthenticatorCustomMD5Realm {public static void main(String[] args) {DefaultSecurityManager securityManager = new DefaultSecurityManager();//设置自定义的MD5+盐+hash散列的RealmCustomMD5Realm md5Realm = new CustomMD5Realm();//设置自定义的realm使用hash凭证匹配器,来改变密码校验方式HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();hashedCredentialsMatcher.setHashAlgorithmName("MD5");//设置hash匹配器算法hashedCredentialsMatcher.setHashIterations(1024);//设置散列次数md5Realm.setCredentialsMatcher(hashedCredentialsMatcher);securityManager.setRealm(md5Realm);SecurityUtils.setSecurityManager(securityManager);Subject subject = SecurityUtils.getSubject();//创建token令牌//用户登录使用明文密码访问UsernamePasswordToken token = new UsernamePasswordToken("achang", "123456");try {subject.login(token);//用户登录System.out.println("登录成功~~");} catch (UnknownAccountException e) {e.printStackTrace();System.out.println("用户名错误!!");}catch (IncorrectCredentialsException e){e.printStackTrace();System.out.println("密码错误!!!");}if(subject.isAuthenticated()){//基于角色权限管理boolean admin = subject.hasRole("admin");System.out.println(admin);//基于多角色权限控制,hasAllRoles只要有一个该subject不含有,就返回falseboolean roles = subject.hasAllRoles(Arrays.asList("admin","super"));System.out.println(roles);//是否具有其中一个角色,返回布尔数组,含有就是t,不含有就是fboolean[] booleans = subject.hasRoles(Arrays.asList("admin","super","user"));// 基于权限字符串的访问控制,资源标识符:操作:资源类型boolean permitted = subject.isPermitted("product:create:001");boolean user = subject.isPermitted("user:update");System.out.println(permitted);System.out.println(user);//分别具有哪些权限boolean[] permitted1 = subject.isPermitted("product:create:001", "user:update");//同时具有哪些权限boolean permittedAll = subject.isPermittedAll("product:create:001", "user:update");}}}
整合SpringBoot项目实战
零、整合思路
一、创建springboot项目
二、引入shiro依赖
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-starter</artifactId><version>1.5.3</version>
</dependency>
三、配置shiro环境
1.配置shiroFilterFactoryBean
@Configuration
public class ShiroConfig {//1、shiroFilter//负责拦截所有请求@Beanpublic ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager){ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();//注入安全管理器shiroFilterFactoryBean.setSecurityManager(securityManager);//设置受限资源HashMap<String, String> map = new HashMap<>();map.put("/index.jsp","authc");//authc 请求这个资源,需要认证授权shiroFilterFactoryBean.setFilterChainDefinitionMap(map);//默认认证界面路径shiroFilterFactoryBean.setLoginUrl("/login.jsp");return shiroFilterFactoryBean;}//2、安全管理器@Beanpublic DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm){DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();defaultWebSecurityManager.setRealm(realm);return defaultWebSecurityManager;}//3、自定义Realm@Bean@Primarypublic Realm getRealm(){return new CustomRealm();}}
3.创建自定义realm
//自定义Realm
public class CustomRealm extends AuthorizingRealm {@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {return null;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {return null;}
}
4.编写控制器跳转至index.html
@Controller
public class IndexController {@RequestMapping("index")public String index(){System.out.println("跳转至主页");return "index";}
}
5.启动springboot应用访问index
- 注意:
- 默认在配置好shiro环境后默认环境中没有对项目中任何资源进行权限控制,所有现在项目中所有资源都可以通过路径访问
6.加入权限控制
-
修改ShiroFilterFactoryBean配置
//设置受限资源 HashMap<String, String> map = new HashMap<>(); map.put("/index.jsp","authc");//authc 请求这个资源,需要认证授权 //map.put("/**","authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(map);//默认认证界面路径 shiroFilterFactoryBean.setLoginUrl("/login.jsp");
- /** 代表拦截项目中一切资源 authc 代表shiro中的一个filter的别名,详细内容看文档的shirofilter列表
7.重启项目访问查看
四、常见过滤器
- 注意: shiro提供和多个默认的过滤器,我们可以用这些过滤器来配置控制指定url的权限:
配置缩写 | 对应的过滤器 | 功能 |
---|---|---|
anon | AnonymousFilter | 指定url可以匿名访问 |
authc | FormAuthenticationFilter | 指定url需要form表单登录,默认会从请求中获取username 、password ,rememberMe 等参数并尝试登录,如果登录不了就会跳转到loginUrl配置的路径。我们也可以用这个过滤器做默认的登录逻辑,但是一般都是我们自己在控制器写登录逻辑的,自己写的话出错返回的信息都可以定制嘛。 |
authcBasic | BasicHttpAuthenticationFilter | 指定url需要basic登录 |
logout | LogoutFilter | 登出过滤器,配置指定url就可以实现退出功能,非常方便 |
noSessionCreation | NoSessionCreationFilter | 禁止创建会话 |
perms | PermissionsAuthorizationFilter | 需要指定权限才能访问 |
port | PortFilter | 需要指定端口才能访问 |
rest | HttpMethodPermissionFilter | 将http请求方法转化成相应的动词来构造一个权限字符串,这个感觉意义不大,有兴趣自己看源码的注释 |
roles | RolesAuthorizationFilter | 需要指定角色才能访问 |
ssl | SslFilter | 需要https请求才能访问 |
user | UserFilter | 需要已登录或“记住我”的用户才能访问 |
五、认证实现
1. 在login.jsp中开发认证界面
<form action="${pageContext.request.contextPath}/user/login" method="post">用户名:<input type="text" name="username" > <br/>密码 : <input type="text" name="password"> <br><input type="submit" value="登录">
</form>
2. 开发controller
@Controller
@RequestMapping("user")
public class UserController {/*** 用来处理身份认证* @param username* @param password* @return*/@RequestMapping("login")public String login(String username,String password){//获取主体对象Subject subject = SecurityUtils.getSubject();try {subject.login(new UsernamePasswordToken(username,password));return "redirect:/index.jsp";} catch (UnknownAccountException e) {e.printStackTrace();System.out.println("用户名错误!");}catch (IncorrectCredentialsException e){e.printStackTrace();System.out.println("密码错误!");}return "redirect:/login.jsp";}
}
- 在认证过程中使用subject.login进行认证
3.开发realm中返回静态数据(未连接数据库)
@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println("==========================");String principal = (String) token.getPrincipal();if("achang".equals(principal)){return new SimpleAuthenticationInfo(principal,"123456",this.getName());}return null;}
}
4.启动项目以realm中定义静态数据进行认证
- 认证功能没有md5和随机盐的认证就实现啦
六、退出认证
1.开发页面退出连接
2.开发controller
@Controller
@RequestMapping("user")
public class UserController {/*** 退出登录**/@RequestMapping("logout")public String logout(){Subject subject = SecurityUtils.getSubject();subject.logout();//退出用户return "redirect:/login.jsp";}
}
3.修改退出连接访问退出路径
4.退出之后访问受限资源立即返回认证界面
七、MD5、Salt的认证实现
1.开发数据库注册
0.开发注册界面
<h1>用户注册</h1>
<form action="${pageContext.request.contextPath}/user/register" method="post">用户名:<input type="text" name="username" > <br/>密码 : <input type="text" name="password"> <br><input type="submit" value="立即注册">
</form>
1.创建数据表结构
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (`id` int(6) NOT NULL AUTO_INCREMENT,`username` varchar(40) DEFAULT NULL,`password` varchar(40) DEFAULT NULL,`salt` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;SET FOREIGN_KEY_CHECKS = 1;
2.项目引入依赖
<!--mybatis相关依赖-->
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.2</version>
</dependency><!--mysql-->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.38</version>
</dependency><!--druid-->
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.19</version>
</dependency>
3.配置application.properties配置文件
server.port=8888
server.servlet.context-path=/shiro
spring.application.name=shirospring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp
#新增配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/shiro?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=rootmybatis.type-aliases-package=com.achang.springboot_jsp_shiro.entity
mybatis.mapper-locations=classpath:com/achang/mapper/*.xml
4.创建entity
@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class User {private String id;private String username;private String password;private String salt;
}
5.创建DAO接口
@Mapper
public interface UserDAO {void save(User user);
}
6.开发mapper配置文件
<insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id">insert into t_user values(#{id},#{username},#{password},#{salt})
</insert>
7.开发service接口
public interface UserService {//注册用户方法void register(User user);
}
8.创建salt工具类
public class SaltUtils {/*** 生成salt的静态方法* @param n* @return*/public static String getSalt(int n){char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890!@#$%^&*()".toCharArray();StringBuilder sb = new StringBuilder();for (int i = 0; i < n; i++) {char aChar = chars[new Random().nextInt(chars.length)];sb.append(aChar);}return sb.toString();}
}
9.开发service实现类
@Service
@Transactional
public class UserServiceImpl implements UserService {@Autowiredprivate UserDAO userDAO;@Overridepublic void register(User user) {//处理业务调用dao//1.生成随机盐String salt = SaltUtils.getSalt(8);//2.将随机盐保存到数据user.setSalt(salt);//3.明文密码进行md5 + salt + hash散列Md5Hash md5Hash = new Md5Hash(user.getPassword(),salt,1024);user.setPassword(md5Hash.toHex());userDAO.save(user);}
}
10.开发Controller
@Controller
@RequestMapping("user")
public class UserController {@Autowiredprivate UserService userService;/*** 用户注册*/@RequestMapping("register")public String register(User user) {try {userService.register(user);return "redirect:/login.jsp";}catch (Exception e){e.printStackTrace();return "redirect:/register.jsp";}}
}
11.启动项目进行注册
2.开发数据库认证
0.开发DAO
@Mapper
public interface UserDAO {void save(User user);//根据身份信息认证的方法User findByUserName(String username);
}
1.开发mapper配置文件
<select id="findByUserName" parameterType="String" resultType="User">select id,username,password,salt from t_userwhere username = #{username}
</select>
2.开发Service接口
public interface UserService {//注册用户方法void register(User user);//根据用户名查询业务的方法User findByUserName(String username);
}
3.开发Service实现类
@Service("userService")
@Transactional
public class UserServiceImpl implements UserService {@Autowiredprivate UserDAO userDAO;@Overridepublic User findByUserName(String username) {return userDAO.findByUserName(username);}
}
4.开发在工厂中获取bean对象的工具类
@Component
public class ApplicationContextUtils implements ApplicationContextAware {private static ApplicationContext context;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.context = applicationContext;}//根据bean名字获取工厂中指定bean 对象public static Object getBean(String beanName){return context.getBean(beanName);}
}
5.修改自定义realm
@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println("==========================");//根据身份信息String principal = (String) token.getPrincipal();//在工厂中获取service对象UserService userService = (UserService) ApplicationContextUtils.getBean("userService");//根据身份信息查询User user = userService.findByUserName(principal);if(!ObjectUtils.isEmpty(user)){//返回数据库信息return new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),ByteSource.Util.bytes(user.getSalt()),this.getName());}return null;}
6.修改ShiroConfig中realm使用凭证匹配器以及hash散列
@Bean
public Realm getRealm(){CustomerRealm customerRealm = new CustomerRealm();//设置hashed凭证匹配器HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();//设置md5加密credentialsMatcher.setHashAlgorithmName("MD5");//设置散列次数credentialsMatcher.setHashIterations(1024);customerRealm.setCredentialsMatcher(credentialsMatcher);return customerRealm;
}
八、授权实现
0.页面资源授权
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %><shiro:hasAnyRoles name="user,admin"><li><a href="">用户管理</a><ul><shiro:hasPermission name="user:add:*"><li><a href="">添加</a></li></shiro:hasPermission><shiro:hasPermission name="user:delete:*"><li><a href="">删除</a></li></shiro:hasPermission><shiro:hasPermission name="user:update:*"><li><a href="">修改</a></li></shiro:hasPermission><shiro:hasPermission name="user:find:*"><li><a href="">查询</a></li></shiro:hasPermission></ul></li></shiro:hasAnyRoles><shiro:hasRole name="admin"><li><a href="">商品管理</a></li><li><a href="">订单管理</a></li><li><a href="">物流管理</a></li></shiro:hasRole>
1.代码方式授权
@RequestMapping("save")
public String save(){System.out.println("进入方法");//获取主体对象Subject subject = SecurityUtils.getSubject();//代码方式if (subject.hasRole("admin")) {System.out.println("保存订单!");}else{System.out.println("无权访问!");}//基于权限字符串//....return "redirect:/index.jsp";
}
2.方法调用授权
- @RequiresRoles 用来基于角色进行授权
- @RequiresPermissions 用来基于权限进行授权
@RequiresRoles(value={"admin","user"})//用来判断角色 同时具有 admin user
@RequiresPermissions("user:update:01") //用来判断权限字符串
@RequestMapping("save")
public String save(){System.out.println("进入方法");return "redirect:/index.jsp";
}
3.授权数据持久化
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for t_pers
-- ----------------------------
DROP TABLE IF EXISTS `t_pers`;
CREATE TABLE `t_pers` (`id` int(6) NOT NULL AUTO_INCREMENT,`name` varchar(80) DEFAULT NULL,`url` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ----------------------------
-- Table structure for t_role
-- ----------------------------
DROP TABLE IF EXISTS `t_role`;
CREATE TABLE `t_role` (`id` int(6) NOT NULL AUTO_INCREMENT,`name` varchar(60) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ----------------------------
-- Table structure for t_role_perms
-- ----------------------------
DROP TABLE IF EXISTS `t_role_perms`;
CREATE TABLE `t_role_perms` (`id` int(6) NOT NULL,`roleid` int(6) DEFAULT NULL,`permsid` int(6) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (`id` int(6) NOT NULL AUTO_INCREMENT,`username` varchar(40) DEFAULT NULL,`password` varchar(40) DEFAULT NULL,`salt` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;-- ----------------------------
-- Table structure for t_user_role
-- ----------------------------
DROP TABLE IF EXISTS `t_user_role`;
CREATE TABLE `t_user_role` (`id` int(6) NOT NULL,`userid` int(6) DEFAULT NULL,`roleid` int(6) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;SET FOREIGN_KEY_CHECKS = 1;
4.创建dao方法
//根据用户名查询所有角色
User findRolesByUserName(String username);
//根据角色id查询权限集合
List<Perms> findPermsByRoleId(String id);
5.mapper实现
<resultMap id="userMap" type="User"><id column="uid" property="id"/><result column="username" property="username"/><!--角色信息--><collection property="roles" javaType="list" ofType="Role"><id column="id" property="id"/><result column="rname" property="name"/></collection></resultMap><select id="findRolesByUserName" parameterType="String" resultMap="userMap">SELECT u.id uid,u.username,r.id,r.NAME rnameFROM t_user uLEFT JOIN t_user_role urON u.id=ur.useridLEFT JOIN t_role rON ur.roleid=r.idWHERE u.username=#{username}</select><select id="findPermsByRoleId" parameterType="String" resultType="Perms">SELECT p.id,p.NAME,p.url,r.NAMEFROM t_role rLEFT JOIN t_role_perms rpON r.id=rp.roleidLEFT JOIN t_perms p ON rp.permsid=p.idWHERE r.id=#{id}</select>
6.Service接口
//根据用户名查询所有角色
User findRolesByUserName(String username);
//根据角色id查询权限集合
List<Perms> findPermsByRoleId(String id);
7.Service实现
@Override
public List<Perms> findPermsByRoleId(String id) {return userDAO.findPermsByRoleId(id);
}@Override
public User findRolesByUserName(String username) {return userDAO.findRolesByUserName(username);
}
8.修改自定义realm
public class CustomerRealm extends AuthorizingRealm {@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//获取身份信息String primaryPrincipal = (String) principals.getPrimaryPrincipal();System.out.println("调用授权验证: "+primaryPrincipal);//根据主身份信息获取角色 和 权限信息UserService userService = (UserService) ApplicationContextUtils.getBean("userService");User user = userService.findRolesByUserName(primaryPrincipal);//授权角色信息if(!CollectionUtils.isEmpty(user.getRoles())){SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();user.getRoles().forEach(role->{simpleAuthorizationInfo.addRole(role.getName());//权限信息List<Perms> perms = userService.findPermsByRoleId(role.getId());if(!CollectionUtils.isEmpty(perms)){perms.forEach(perm->{simpleAuthorizationInfo.addStringPermission(perm.getName());});}});return simpleAuthorizationInfo;}return null;}
}
9.启动测试
九、使用CacheManager
1.Cache 作用
- Cache 缓存: 计算机内存中一段数据
- 作用: 用来减轻DB的访问压力,从而提高系统的查询效率
- 流程:
2.使用shiro中默认EhCache实现缓存
本地缓存
①引入依赖
<!--引入shiro和ehcache-->
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-ehcache</artifactId><!--注意版本,要与shiro一致--><version>1.5.3</version>
</dependency>
②开启缓存
//3.创建自定义realm@Beanpublic Realm getRealm(){CustomerRealm customerRealm = new CustomerRealm();//修改凭证校验匹配器HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();//设置加密算法为md5credentialsMatcher.setHashAlgorithmName("MD5");//设置散列次数credentialsMatcher.setHashIterations(1024);customerRealm.setCredentialsMatcher(credentialsMatcher);//开启缓存管理器customerRealm.setCachingEnabled(true);//开启全局缓存customerRealm.setAuthenticationCacheingEnabled(true);//开启认证缓存customerRealm.setAuthorizationCachingEnabled(true);//开启授权缓存customerRealm.setCacheManager(new EhCacheManager());return customerRealm;}
③启动刷新页面进行测试
- 注意:如果控制台没有任何sql展示说明缓存已经开启
3.shiro中使用Redis作为缓存实现
①引入redis依赖
<!--redis整合springboot-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
②配置redis连接
spring.redis.port=6379
spring.redis.host=localhost
spring.redis.database=0
3.启动redis服务
➜ bin ls
dump.rdb redis-check-aof redis-cli redis-server redis.conf
redis-benchmark redis-check-rdb redis-sentinel redis-trib.rb
➜ bin ./redis-server redis.conf
4.开发RedisCacheManager
public class RedisCacheManager implements CacheManager {@Overridepublic <K, V> Cache<K, V> getCache(String cacheName) throws CacheException {System.out.println("缓存名称: "+cacheName);return new RedisCache<K,V>(cacheName);}
}
5.开RedisCache实现
public class RedisCache<K,V> implements Cache<K,V> {private String cacheName;public RedisCache() {}public RedisCache(String cacheName) {this.cacheName = cacheName;}@Overridepublic V get(K k) throws CacheException {System.out.println("获取缓存:"+ k);return (V) getRedisTemplate().opsForHash().get(this.cacheName,k.toString());}@Overridepublic V put(K k, V v) throws CacheException {System.out.println("设置缓存key: "+k+" value:"+v);getRedisTemplate().opsForHash().put(this.cacheName,k.toString(),v);return null;}@Overridepublic V remove(K k) throws CacheException {return (V) getRedisTemplate().opsForHash().delete(this.cacheName,k.toString());}@Overridepublic v remove(k k) throws CacheException {return (v) getRedisTemplate().opsForHash().delete(this.cacheName,k.toString());}@Overridepublic void clear() throws CacheException {getRedisTemplate().delete(this.cacheName);}@Overridepublic int size() {return getRedisTemplate().opsForHash().size(this.cacheName).intValue();}@Overridepublic Set<k> keys() {return getRedisTemplate().opsForHash().keys(this.cacheName);}@Overridepublic Collection<v> values() {return getRedisTemplate().opsForHash().values(this.cacheName);}private RedisTemplate getRedisTemplate(){RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtils.getBean("redisTemplate");redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setHashKeySerializer(new StringRedisSerializer());return redisTemplate;}//封装获取redisTemplateprivate RedisTemplate getRedisTemplate(){RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtils.getBean("redisTemplate");redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setHashKeySerializer(new StringRedisSerializer());return redisTemplate;}
}
6.启动项目测试发现报错
-
错误解释: 由于shiro中提供的simpleByteSource实现没有实现序列化,所有在认证时出现错误信息
-
解决方案: 需要自动salt实现序列化
-
自定义salt实现序列化
//自定义salt实现 实现序列化接口 public class MyByteSource extends SimpleByteSource implements Serializable {public MyByteSource(String string) {super(string);} }
-
在realm中使用自定义salt
@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println("==========================");//根据身份信息String principal = (String) token.getPrincipal();//在工厂中获取service对象UserService userService = (UserService) ApplicationContextUtils.getBean("userService");User user = userService.findByUserName(principal);if(!ObjectUtils.isEmpty(user)){return new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(), new MyByteSource(user.getSalt()),this.getName());}return null; }
-
7.再次启动测试,发现可以成功放入redis缓存
4. 加入验证码验证
0.开发页面加入验证码
-
开发控制器
@RequestMapping("getImage") public void getImage(HttpSession session, HttpServletResponse response) throws IOException {//生成验证码String code = VerifyCodeUtils.generateVerifyCode(4);//验证码放入sessionsession.setAttribute("code",code);//验证码存入图片ServletOutputStream os = response.getOutputStream();response.setContentType("image/png");VerifyCodeUtils.outputImage(220,60,os,code); }
-
放行验证码
-
开发页面
-
修改认证流程
@RequestMapping("login")public String login(String username, String password,String code,HttpSession session) {//比较验证码String codes = (String) session.getAttribute("code");try {if (codes.equalsIgnoreCase(code)){//获取主体对象Subject subject = SecurityUtils.getSubject();subject.login(new UsernamePasswordToken(username, password));return "redirect:/index.jsp";}else{throw new RuntimeException("验证码错误!");}} catch (UnknownAccountException e) {e.printStackTrace();System.out.println("用户名错误!");} catch (IncorrectCredentialsException e) {e.printStackTrace();System.out.println("密码错误!");}catch (Exception e){e.printStackTrace();System.out.println(e.getMessage());}return "redirect:/login.jsp";}
-
修改salt不能序列化的问题
//自定义salt实现 实现序列化接口 public class MyByteSource implements ByteSource,Serializable {private byte[] bytes;private String cachedHex;private String cachedBase64;//加入无参数构造方法实现序列化和反序列化public MyByteSource(){}public MyByteSource(byte[] bytes) {this.bytes = bytes;}public MyByteSource(char[] chars) {this.bytes = CodecSupport.toBytes(chars);}public MyByteSource(String string) {this.bytes = CodecSupport.toBytes(string);}public MyByteSource(ByteSource source) {this.bytes = source.getBytes();}public MyByteSource(File file) {this.bytes = (new MyByteSource.BytesHelper()).getBytes(file);}public MyByteSource(InputStream stream) {this.bytes = (new MyByteSource.BytesHelper()).getBytes(stream);}public static boolean isCompatible(Object o) {return o instanceof byte[] || o instanceof char[] || o instanceof String || o instanceof ByteSource || o instanceof File || o instanceof InputStream;}public byte[] getBytes() {return this.bytes;}public boolean isEmpty() {return this.bytes == null || this.bytes.length == 0;}public String toHex() {if (this.cachedHex == null) {this.cachedHex = Hex.encodeToString(this.getBytes());}return this.cachedHex;}public String toBase64() {if (this.cachedBase64 == null) {this.cachedBase64 = Base64.encodeToString(this.getBytes());}return this.cachedBase64;}public String toString() {return this.toBase64();}public int hashCode() {return this.bytes != null && this.bytes.length != 0 ? Arrays.hashCode(this.bytes) : 0;}public boolean equals(Object o) {if (o == this) {return true;} else if (o instanceof ByteSource) {ByteSource bs = (ByteSource)o;return Arrays.equals(this.getBytes(), bs.getBytes());} else {return false;}}private static final class BytesHelper extends CodecSupport {private BytesHelper() {}public byte[] getBytes(File file) {return this.toBytes(file);}public byte[] getBytes(InputStream stream) {return this.toBytes(stream);}} }
相关文章
- 打印菱形、三角形-课后程序(JavaScript前端开发案例教程-黑马程序员编著-第2章-课后作业)
【案例2-10】打印菱形、三角形 一、案例描述 考核知识点 for双重循环 练习目标 掌握for循环应用。打印出菱形打印出三角形。 需求分析 在本案例中我们将用JavaScript代码在页面中用“*”打印出菱形和三角形。 案例分析 菱形效果如图2-16所示。输入菱形行数6打印菱形 三角形…...
2023/5/11 6:15:22 - flink开发常见问题 —— flink-kafka 依赖版本冲突问题
问题描述 由于 flink / kafka 的版本不断更新,创建项目的时候就应当考虑清楚这几个依赖库的版本问题,尽可能地与实际场景保持一致,比如服务器上部署的 kafka 是哪个版本,flink 是哪个版本,从而确定我们需要开发的是哪…...
2023/6/6 23:36:21 - 汇编语言(1)——寄存器
文章目录1.通用寄存器2.字在寄存器中存储3.确定物理地址的方法4.内存分段表示法5.CS、IP寄存器及代码段6.jmp指令1.通用寄存器 8086中的所有寄存器都是16位的,可以存放两个字节,AX、BX、CX、DX这四个寄存器用来存放一般性的数据,统称为通用寄…...
2023/5/20 21:27:50 - Netty权威指南总结(三)
五、Netty实战技巧:(一) 多线程编程实践:1. Netty中使用多线程的技巧:创建两个NioEventLoopGroup,用于逻辑隔离NIO Acceptor和NIO IO线程。尽量不要在ChannelHandler中启动用户线程(解码后用于将POJO消息派发到后端业务…...
2023/6/7 0:42:32 - 俄语语音语调的7个调型,柯桥俄语培训
在俄语语调的学习和教授过程中,通常将一个句子分为三个部分:调心前部、调心、调心后部。在发音时,各调型内词与词之间的界限消失,各词的首尾音节紧密衔接成为一个整体,而句子中有一个重读音节在语调上和意义上作为该句…...
2023/5/22 19:59:27 - 一位全加器及四位全加器————FPGA
文章目录前言一、一位全加器1、一位全加器的原理图设计2、一位全加器的Verilog编程3、上板效果二、四位全加器1、四位全加器的原理图设计2、四位全加器的Verilog 编程三、总结四、参考资料前言 环境: 1、Quartus18.0 2、vscode 3、基于Intel DE2-115的开发板 一、一…...
2023/6/3 3:51:11 - 在服务器中使用Docker安装Tomcat、同时实现目录挂载、并且部署War包到服务器
文章目录1、Docker中安装Tomcat1.1 搜索tomcat1.2 拉取1.3 查看拉取的镜像2、目录挂载2.1 目录挂载准备2.2 创建容器同时进行挂载2.3 进入容器2.4 测试1、Docker中安装Tomcat 1.1 搜索tomcat docker search tomcat1.2 拉取 docker pull tomcat //我这里拉取最新的。也可以拉…...
2023/3/31 21:25:16 - 【LeetCode】二叉树的前序遍历(递归,迭代,Morris 遍历)
目录 题目要求:给你二叉树的根节点 root ,返回它节点值的 前序 遍历。 方法一:递归 方法二:迭代 思路分析: 复杂度分析 代码展示: 方法三:迭代进阶 思路分析: 代码展示&…...
2023/4/17 18:09:13 - CentOS镜像,RPM,epel位置
1.镜像位置 CentOS官网 1.1 点击下载: 1.2 获取位置 所有获取镜像的列表: 比如获取清华iso镜像: 2.RPM位置 点击下方链接 所有获取镜像的列表: 比如我获取的是清华开源,从此根目录找对应版本的RPM, ht…...
2023/5/28 23:58:36 - 用户空间和内核空间,系统调用
内核空间与用户空间 用户空间和内核空间是操作系统中的两个重要概念。 用户空间是指操作系统为每个进程分配的一块内存空间,用于存储进程的代码、数据和堆栈等信息。在用户空间中运行的程序只能访问自己的内存空间,不能直接访问操作系统的内存空间或硬…...
2023/6/1 14:42:13 - 【Flutter·学习实践·配置】认识配置文件pubspec.yaml
目录 简介 pubspec.yaml 添加Pub仓库 其他依赖方式 依赖本地包 依赖Git 简介 简单说就是包管理工具,类似于Android 提供了 Gradle 来管理依赖,iOS 用 Cocoapods 或 Carthage 来管理依赖,Node 中通过 npm 等。 让我们能很好的管理第三…...
2023/6/7 0:03:37 - day 15 面相对象
day 15 面相对象 编程思维 根据面对问题不同人呈现出来的思维模式不同,可以将编程思维分为三种: 面相过程编程(穷人思想) — 遇到问题马上想到解决这个问题的具体逻辑和步骤 函数式编程(小资思想) — 遇到问题马上想到有没有一个已经存在的函数可以解…...
2023/4/19 3:12:59 - 免费分享一个springboot+vue的办公系统
springbootvue的OA系统项目介绍项目部署项目特点项目展示项目介绍 这是一个采用前后端分离开发的项目,前端采用 Vue 开发、后端采用 SpringBoot Mybatis 开发。 很适合java初学者练手和学习。 前端技术:Vue3.2 Vue-Router Pinia Ant Design Vue 3.X…...
2023/4/21 22:02:53 - UE4 动画蓝图的优化
General Tips当您开始考虑动画使用的性能时,以下是执行优化时可能需要遵循的一些准则。确保满足并行更新的条件在UAnimInstance::NeedsImmediateUpdate中,您可以看到必须满足的所有条件,以避免在游戏线程上运行动画的更新阶段。如…...
2023/5/18 12:17:42 - 深入理解计算机系统(3)_程序的机器级表示
一起来理解计算机系统系列文章目录 1. 大致简介 程序结构篇 1. 信息表示与处理 2. 程序的机器级表示 程序运行篇 程序交互篇 文章目录一起来理解计算机系统系列文章目录一、前言二、本文参考资料三、正文部分3.1 目的 / 目标3.2 程序编码3.2.1 机器级代码3.2.2 代码示例3.2.3…...
2023/5/30 13:59:32 - 刷题打卡day39第九章 动态规划: 62.不同路径 、 63. 不同路径 II
62.不同路径 开始进入二维dp数组的部分。 需要注意的是:二维vectpr数组的定义方式,及初始化: vector<vector<int>> dp(m, vector<int>(n, 0)); 定义一个m行n列的二维数组,初始化为0. class Solution { pub…...
2023/6/5 21:00:38 - 怎么选择项目协作工具,最详细的指南来了!
现代企业要在当前的气候中生存,就必须适应。COVID-19疫情对传统的工作方式提出了质疑,并强调了远程和混合工作模式的重要性。如今,企业必须采用敏捷的策略,以便更轻松地应对挑战,并为员工提供更大程度的灵活性。敏捷状…...
2023/4/23 7:25:17 - 最新版高可用hadoop集群搭建及问题排查
最新版高可用hadoop集群搭建及问题排查 注释 注:本文只针对高可用hadoop集群部署做讲解,如需系统学习hadoop,可参考gitee文档:大数据入门指南 集群架构 集群搭建 前置步骤 所有节点执行 配置hosts: vim /etc/hos…...
2023/5/22 19:59:27 - Linux中wget、yum与apt-get用法及区别
Linux中wget、yum与apt-get用法及区别wget、yum与apt-get区别一、Centos包管理工具 yum1.1 yum源配置1.2 yum命令的基本使用二、Ubuntu包管理工具 apt-get2.1 apt-get基本使用三、下载工具wgetwget、yum与apt-get区别 yum与apt-get都是包管理工具,就像python中的pip…...
2023/6/1 22:59:27 - Visual SVN Server的下载和使用
摘要 代码管理和文件下载管理服务器Visual SVN Server使用相比如git操作更方便,不用指令就可以完成,其次能够上传大文件十分方便 一 安装Visual SVN Server 下载msi文件 进入Visual SVN Server官网下载64bit文件,官网如下: ht…...
2023/6/3 11:28:04
最新文章
- MySQL 开发实践 8 问
1.MySQL读写性能是多少,有哪些性能相关的重要参数? 这里做了几个简单压测实验 机器:8核CPU,8G内存 表结构(尽量模拟业务):12个字段(1个bigint(20)为自增primary key,5个int(11),5个varchar(51…...
2023/6/7 1:13:43 - go-GUI开发:fyne解决中文乱码+注册windows服务
go-GUI框架:fyne教程及解决中文乱码等常见bug 1 fyne教程 fyne教程地址: https://www.topgoer.cn/docs/goday/goday-1crdp17nj4v6phttps://pkg.go.dev/fyne.io/fyne/v2#section-readme 1.1 介绍 简单易用,fyne提供了简单直观的APIÿ…...
2023/6/7 1:12:58 - tomcat中server.xml详解
Tomcat简介 Tomcat是一个基于Java的Web应用服务器,而server.xml是Tomcat的主要配置文件之一。在这个文件中,你可以配置Tomcat的端口、虚拟主机、连接器、安全性等等. 1. Server <Server port"8005" shutdown"SHUTDOWN"><…...
2023/6/7 1:11:50 - 【Linux】基础文件IO、动静态库的制作和使用
基础IO 前言回顾C语言文件IO操作三个标准 系统文件I/O系统调用接口不带mode的open带mode的openwirtereadopen的第二个参数flagsopen返回值文件的管理0,1,2演示文件描述符的分配规则重定向C中的0、1、2输入重定向追加重定向 另一种重定向的方式dup2实现输…...
2023/6/7 1:11:35 - 【算法】【算法杂谈】一种类似于滑动窗口的结构设计
目录 前言问题介绍解决方案代码编写java语言版本c语言版本c语言版本 思考感悟写在最后 前言 当前所有算法都使用测试用例运行过,但是不保证100%的测试用例,如果存在问题务必联系批评指正~ 在此感谢左大神让我对算法有了新的感悟认识! 问题介…...
2023/6/7 1:11:24 - 配置Linux操作系统主机名及网络设置
上一篇我们讲到了如何克隆虚拟机,三台虚拟机Spark01、Spark02和Spark03默认为动态IP地址,若后续重启系统后IP地址便会发生改变,非常不利于实际开发,且虚拟机Spark02和Spark03是通过克隆虚拟机Spark01创建的,这会导致这…...
2023/6/7 1:11:07 - NCUTer 我的创作纪念日(2023-06-06)
前言 大家好,我是NCUTer,今天收到私信,突然发现,我来到CSDN已经2年多了,距离发布第一篇博客已经2年整了。正式规划性的写博客,是在2021年6月底开始的,当时啥也不懂,不知道该怎么去做…...
2023/6/7 1:10:50 - 隐马尔可夫模型在数学建模中的应用及MATLAB实现
2023年9月数学建模国赛期间提供ABCDE题思路加Matlab代码,专栏链接(赛前一个月恢复源码199,欢迎大家订阅):http://t.csdn.cn/Um9Zd 目录 2023年9月数学建模国赛期间提供ABCDE题思路加Matlab代码,专栏链接(赛前一个月恢复源码199,欢迎大家订阅):http://t.csdn.cn/Um9Zd 隐马尔可…...
2023/6/7 1:10:40 - 以安全为底线 共迎机遇和挑战|2023 开放原子全球开源峰会可信基础设施技术分论坛即将启幕
蚂蚁集团的业务领域,对于「可信」有非常高的技术要求。这种可信技术不仅体现在可靠、健壮,也体现在金融领域独有的风控难题以及分布式系统中持续提供服务的续航能力。可信基础设施中有大量的开源项目,而新的机会也在不断涌现。 2023 开放原子…...
2023/6/7 1:09:57 - for...of的实现底层——迭代器
在MDN官网学习for...of的时候,会发现for...of是这么描述的:for...of语句在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环&am…...
2023/6/7 1:07:42 - Java 中的流
输入输出流 在Java中,输入输出流是处理文件和网络数据传输的基本方式。下面是一些Java中常用的输入输出流: 输入流: FileInputStream:用于从文件中读取字节。FileReader:用于从文件中读取字符。BufferedInputStream…...
2023/6/7 1:07:26 - python面向对象操作2(速通版)
目录 一、私有和公有属性的定义和使用 1.公有属性定义和使用 2.私有属性 二、继承 1.应用 2.子类不能用父类的私有方法 3.子类初始化父类 4.子类重写和调用父类方法 5.多层继承 6.多层继承-初始化过程 7.多继承基本格式 8.多层多继承时的初始化问题 9.多继承初始化…...
2023/6/7 1:07:14 - 安装Unity Hub和Unity Editor
1、首先下载UnityHub的安装包: https://unity.com/cn/download 开始您的创意项目并下载 Unity Hub | Unity 2、运行安装包 3、运行Unity Hub 第一次运行Unity Hub会默认弹出登录Unity提示,正常登录就可以了,登录后会在浏览器提示打开 Unity…...
2023/6/7 1:06:29 - 遍历文本文件中的图片信息并复制图片
遍历文本文件中的图片信息并复制图片 数据处理是人工智能算法训练中非常重要的一环。在实际应用中,往往需要使用现有的数据集进行模型训练。然而在实际情况中,有时会因为种种原因需要将数据从一个集合移动到另一个集合。例如,我们需要从一个大型数据集中找到某些特定的图片…...
2023/6/7 1:06:19 - 10万字XX市开发区智慧综治中心平台建设一期工程招标文件word
(一)智慧综治中心信息化平台 需基于“一个平台,多级用户”的原则,利用移动互联网、物联网、大数据、人工智能和地理信息等新一代信息技术,整合辖区多方社会治理数据,建立一个覆盖全区三级综治中心用户的统一…...
2023/6/7 1:05:50 - 面试-Dubbo常见问题
面试-Dubbo 常见问题 1. 什么是Dubbo? Dubbo 是一个RPC框架,包含注册中心,服务提供方,服务消费方,控制台,监控中心。 2. Dubbo启动时依赖服务不可用,会怎么样? Dubbo 启动时会从注册中心拉…...
2023/6/7 1:05:17 - MongoDB简单快速入门
MongoDB简单快速入门 简单介绍应用场景安装与启动基础操作SpringBoot整合MongoDB 简单介绍 MongoDB是一个开源、高性能、无模式的文档型数据库。NoSQL数据库产品中的一种,是最想关系型数据库的非关系型数据库 应用场景 安装与启动 直接将安装的压缩包进行解压&…...
2023/6/7 1:03:59 - 14.Linux压缩解压文件
在 Linux 中,压缩和解压文件是常见的任务之一。下面介绍几个主要的压缩和解压命令: 压缩文件 tar 命令 tar 命令是在 Linux 中最常用的压缩工具之一,它可以将多个文件或目录打包成一个大文件,并进行压缩处理。 将一个目录打包成 …...
2023/6/7 1:03:44 - 17JS08——函数
函数 一、函数的概念二、函数的使用2.1 声明函数2.2 调用函数2.3 函数的封装 三、函数的参数3.1 形参和实参3.2 形参和实参个数不匹配问题3.3 小结 四、函数的返回值4.1 return语句4.2 return终止函数4.3 break、continue、return的区别4.4 案例 五、arguments的使用案例1&…...
2023/6/7 1:03:31 - UE5 Chaos破碎系统学习1
在UE5中,Chaos破碎系统被直接进行了整合,本篇文章就来讲讲chaos的基础使用。 1.基础破碎 1.首先选中需要进行破碎的模型,例如这里选择一个Box,然后切换至Fracture Mode(破碎模式): 2.点击右侧…...
2023/6/7 1:03:19 - ChatGPT是什么语言模型?
ChatGPT是什么语言模型?在自然语言处理(NLP)领域中,大型语言模型一直是一个备受关注的研究方向,GPT-3作为当前最先进的语言模型之一,其性能和应用场景已经被广泛研究和应用。ChatGPT作为基于GPT-3.5架构的大型语言模型,…...
2023/6/7 1:10:48 - 注意!ChatGPT的Plus账号也会被封禁
文 / 高扬(微信公众号:量子论) 最近经常看到有人丢个截图,然后悲伤地说,ChatGPT账号被封了。 这不是账号被封,而是所用的代理节点被OpenAI封了,换个节点即可。 这个截图才是账号真正被封的提示&…...
2023/6/6 23:39:44 - 一键部署个人ChatGPT Web网站
一键部署个人ChatGPT Web网站 githubVercel使用自己的域名 本文将向大家介绍如何通过Github和Vercel这两个具,轻松搭建自己的ChatGPT Web网站,并且我们还可以添加密码保护以防止恶意滥用。 github 首先,我们需要拥有一个Github账号和Vercel账࿰…...
2023/6/6 22:47:18 - 【ChatGPT】基于tensorflow2实现transformer(GPT-4)
请记住,您是一位NLP领域的专家和优秀的算法工程师。使用带有 tensorflow2.0 subclass api 的 python 从头开始实现 transformer 模型。 全部内容如下: 构建transformer模型架构和依赖层;生成并预处理一些假样本数据,用于训练上面…...
2023/6/6 22:44:33 - ChatGPT的20种用法,挺不错建议收藏
一、闲聊机器人 用途:这个不多说了,用来闲聊体验感真的很不错。 二、关键字提取 用途:NLP任务的重要作用,关键字提取! 三、将产品描述转变为广告 用途: 这个功能对于商家来说太棒了。 四、情感分析 用途…...
2023/6/6 22:40:57 - Openai+Coursera: ChatGPT Prompt Engineering(一)
想和大家分享一下最近学习的Coursera和openai联合打造ChatGPT Prompt Engineering在线课程,下面是通过API来访问ChatGPT的主要代码: import openaiopenai.api_key XXXXXXXXXdef get_completion(prompt, model"gpt-3.5-turbo"):messages [{&…...
2023/6/6 22:28:45 - 本地化部署AI语言模型RWKV指南,ChatGPT顿时感觉不香了。
之前由于ChatGpt处处受限,又没法注册的同学们有福了,我们可以在自己电脑上本地化部署一套AI语言模型,且对于电脑配置要求也不是非常高,对它就是RWKV。 关于RWKV RWKV是一个开源且允许商用的大语言模型,灵活性很高且极…...
2023/6/6 21:04:59 - 基于Python+百度语音的智能语音ChatGPT聊天机器人(机器学习+深度学习+语义识别)含全部工程源码 适合个人二次开发
目录 前言总体设计系统整体结构图系统流程图 运行环境Python 环境Pycharm 环境ChatterBot 环境 模块实现1. 模型构建2. 服务器端3. 客户端4. 语音录入5. 接口调用6.模型训练及保存 系统测试1. 模型效果2. 模型应用 源代码下载地址其它资料下载 前言 本项目基于机器学习和语义识…...
2023/6/6 16:54:09 - 创造之境:Stable Diffusion + chatGPT下的自动绘图探索
什么是Stable Diffusion Stable Diffusion 是在2022年发布的深度学习文本到图像生成模型。它主要用于根据文字的描述生成详细图像,尽管它也可以应用于其他任务,如内插绘制、外插绘制,以及在提示词(英语)指导下生成图生…...
2023/6/6 16:12:03 - 4个ChatGPT拓展出来的工具
现在ChatGPT 相关 的方向非常的多,各个大厂一个一个推出了自己的大模型,从国外到国内,ChatGPT 相关 也有几十个,这是大厂的方向。 对于比较小的团队,很多都是在ChatGPT 的基础上进行的开发,下面罗列出4个在…...
2023/6/6 14:10:23 - 了解Chatgpt key token计价或扣费说明
了解Chatgpt key及token计费方式 Token及费用说明 token 与 文字 的换算 OpenAI的定价是基于token的,对于英文文本,1个token大约是4个字符或0.75个单词。通常1000个Token约等于750个英文单词或者400~500个汉字。 花费 1000个token的价格…...
2023/6/6 12:58:22 - 如何用ChatGpt开发小游戏
随着人工智能的快速发展,自然语言处理模型ChatGPT在各种应用中得到了广泛的应用。其中,开发小游戏是一个有趣而具有挑战性的任务。本文将介绍如何使用ChatGPT开发小游戏,并提供一些示例和技巧,帮助读者了解如何利用ChatGPT打造自己…...
2023/6/6 12:20:52 - ChatGPT唤醒AI游戏:AIGC持续走深,游戏或成AI最佳抓手
随着人工智能技术的不断发展,AI在游戏行业的应用日益深入。本文将详细探讨ChatGPT在AI游戏领域的应用,以及游戏如何成为AI技术的最佳抓手。让我们一起探讨这个有趣且充满潜力的领域。 一、引言 人工智能在各行各业都取得了巨大的成功,而游戏…...
2023/6/6 11:31:05 - 【ChatGPT免费使用,无限制的问答和绘图模式】文末还介绍了最强的AI绘图模型演示,提供三重模型免费网站地址,阐述不要过分依赖ChatGPT,使用前也应该多思考观点
分享一个免费且无需登录即可使用,结合问答与绘图模型, 可自由调节模型参数的公益网站: https://shdily.com 绘图一定要多描述特征(推荐英语),才能有更好的效果 注意: 此网站在使用腾讯服务器…...
2023/6/6 10:53:10 - 【原创】免费,不限量,使用OpenAI ChatGPT方法大揭秘
文章目录 微软的Edge浏览器集成WeTab插件就可以免费使用ChatGPT1、安装最新版的Edge浏览器2、选中浏览器的配置中的扩展3、在启动新页时,就可以看到chatGPT了4、这就可以免费使用chatGPT啦 微软的Edge浏览器集成WeTab插件就可以免费使用ChatGPT 1、安装最新版的Edg…...
2023/6/6 9:46:10 - 如何安装ChatGPT?
ChatGPT是一款流行的在线聊天机器人,可帮助您与朋友、家人或客户进行沟通交流。如果您正在寻找一种快捷便利的工具来提高与他人的沟通能力,那么ChatGPT可能是一个不错的选择。 那么,如何在您自己的设备上安装ChatGPT呢?这里为您提…...
2023/6/6 8:50:34 - 【ChatGPT白嫖大全】什么年代了?还在看传统文章?
💓博主CSDN主页:杭电码农-NEO💓 ⏩专栏分类:学习番外篇⏪ 🚚代码仓库:NEO的学习日记🚚 🌹关注我🫵带你了解更多热点知识 🔝🔝 白嫖大法 1. 前言🚩2. 需要…...
2023/6/6 7:38:28 - Elasticsearch:如何使用 Elasticsearch 以自然语言提示 ChatGPT
作者:Enrico Zimuel 这些天每个人都在谈论 ChatGPT。 这种大型语言模型 (LLM) 的一项很酷的功能是能够生成代码。 我们用它来生成 Elasticsearch DSL 查询。 目标是在 Elasticsearch 中搜索 “给我股票指数中 2017 年的前 10 个文档(Give me the first 1…...
2023/6/6 2:09:15 - 目前可用的ChatGPT网站(6/5/2023更新)
本文意在整理可用gpt-3.5、gpt-4.0等网站。 本文主要是方便自己翻阅,如对您也有所帮助,不胜荣幸~ 文章目录 GPTTalkChat机器人wuguokai.cnWeBoT(GPT-4)bing.com(GPT-4)HuggingChat总结 GPTTalk 网址:https://gpttalk.live/gpt-3.5 Chat机器…...
2023/6/7 0:10:38 - Chatgpt中文版无需代理,ChatGPT镜像
Chatgpt中文版无需代理 网站ChatGPT中文版 ChatGPT中文版是一个基于人工智能技术的聊天机器人,它可以模拟人类的自然语言交互,回答用户的各种问题和提供各种服务。它的核心技术是GPT(Generative Pre-trained Transformer)模型&am…...
2023/6/6 23:03:34 - ChatGPT中文版Prompt提示工程超详细指南《提示工程简介及示例》Github最新破万星项目Meta AI前工程师解密百万年薪提示工程师GPT-4模型优化利器(一)
提示工程简介及示例 前言Introduction 导言提示工程简介什么是提示工程大语言模型设置基础提示词提示词格式提示词要素设计提示的通用技巧从简单开始指令具体性避免不精确做还是不做? 提示词示例文本概括信息提取问答文本分类对话代码生成推理 说明参考资料其它资料…...
2023/6/6 22:18:14 - AI(二):初体验(Cursor、Copilot、Bito、Notion、ChatExcel、Gamma、Tome、ChatPDF、AI-Video、SD、ChatGPTAPI、Midjourney)
Cursor Cursor官网下载:https://www.cursor.so/ && https://github.com/getcursor/cursor Cursor.so是一款基于GPT的代码生成工具,它可以帮助开发者快速生成代码,提高开发效率。GPT是一种自然语言处理技术,可以根据输入…...
2023/6/5 20:15:16 - Pandas+ChatGPT强强结合诞生PandasAI,数据分析师行业要变天了?
大家好,我是千与千寻,可以叫我千寻,我自己主要的编程语言是Python和Java。 说到Python编程语言,使用Python语言主要使用的是数据科学领域的从业者。 Python编程语言之所以在数据科学领域十分火热,源于Python语言的三大数据科学工作包,NumPy,Pandas,SciPy。 以下是三…...
2023/6/5 20:02:13 - 效率神器!神级ChatGPT浏览器插件分享
大家好,我是卷了又没卷,薛定谔的卷的AI算法工程师「陈城南」~ 担任某大厂的算法工程师,带来最新的前沿AI知识和工具,欢迎大家交流~,后续我还会分享更多 AI 有趣工具和实用玩法,包括AI相关技术、ChatGPT、AI…...
2023/6/5 19:35:10 - Ex-ChatGPT本地部署+Azure OpenAI接口配置+docker部署服务
Ex-ChatGPT项目分为 Ex-ChatGPT 和 WebChatGPTEnhance 两部分,Ex-ChatGPT启动后是个web服务,通过访问ip端口体验; WebChatGPTEnhance可编译生成一个浏览器插件,Chrome或者Microsoft edge浏览器可以安装该插件,点击该插…...
2023/6/5 18:36:13 - 【AI聊天丨 ChatGPT应用案例一】— 仅用30分钟,ChatGPT帮你完成专利交底书!
Hi,大家好,我是零点壹客,今天主要也是想和大家一起唠唠ChatGPT, 尤其这两个月,ChatGPT出奇的火,想必各位圈友们或多或少的都已经有些了解。 ChatGPT的出现很大程度上已经改变了我们的工作方式,尤…...
2023/6/5 18:10:19 - ChatGPT与网络安全
文章目录 一、“AI用于攻击”二、“AI用于安全(防御)”三、“AI的防御”四、“AI被攻击” ChatGPT作为基于生成式预训练模型(GPT)的聊天机器人,其核心技术是自然语言处理(NLP)。随着NLP技术的不…...
2023/6/6 23:47:34 - 三联周刊和ChatGPT一起专访了《人类简史》作者尤瓦拉·赫拉利
*本文为「三联生活周刊」原创内容 “人类文化基于语言。而因为人工智能已经破解了语言,它现在可以开始创造文化。” 主笔 | 苗千 记者|肖楚舟 张宇琦 编辑|曾焱 尤瓦尔赫拉利(Yuval Noah Harari)以其《人类简史》《未来简史》和《今日简史》等风靡全球的著作,成为当…...
2023/6/5 14:33:50 - ChatGPT让我变成了“超人”-如何提升团队30%效能质量提高100%的阶段性总结报告
创作背景 CHATGPT刚出现时我的内心有一万匹“马”在奔腾,我是排斥的、BS的、甚至关掉屏敝掉相关新闻、连家里电视机的插线都拨掉。因为它的表现真的伤到了我的自尊。 这样的情绪源至我自己的“不自信”,不自信的前提是因为听到的东西太过于有“冲击性”了…...
2023/6/6 14:43:49 - 国内使用chatGPT插件
无需任何繁琐操作,只要你一打开edge浏览器就能使用chatGPT,还要什么自行车! 那么如何使用呢?其实操作是非常简单的! 步骤 第一步:下载edge浏览器 edge浏览器一般Windows10系统都自带了,没有的…...
2023/6/6 13:51:46 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57