Я использую dart для разработки приложения flutter для электронной коммерции, поэтому здесь, когда я пытаюсь создать страницу редактирования профиля, мне нужно передать токен со страницы входа в систему
Так как я использую rest api в качестве back end, я не могу редактировать, поэтому я обнаружил, что токен должен быть передан, от входа в этот change-profile api, чтобы пользователь мог успешно редактировать свои данные .
Future<void> updateProfile() async {
String url = "http://167.71.232.83:8000/myprofile/${userId}/";
// Build the query parameters with updated user information
Map<String, String> queryParams = {
"email": _emailController.text,
"password": passwordController.text,
"repassword": repasswordController.text,
"firstname": firstname.text,
"lastname": lastname.text,
"phonenumber": phonenumber.text,
"state": state.text,
"city": city.text,
"Zip": zip.text,
"mailing": _value.toString(),
"referred_by": selectedItem,
"flag": "business",
"businessname": businesscontroller.text,
};
String queryString = Uri(queryParameters: queryParams).query;
url += '?' + queryString;
try {
final response = await http.put(
Uri.parse(url),
headers: {
"Content-Type": "application/json",
"User-Agent": "PostmanRuntime/7.28.4",
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive",
},
);
var data = jsonDecode(response.body);
print(url);
print(response.statusCode);
print(data);
if (response.statusCode == 200) {
// Success
_showSuccessDialog();
// Navigate to the next page or perform any other actions
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => BottomPage(),
),
);
} else {
// Error
_showErrorDialog('Failed to update profile. Please try again.');
}
print(response.body);
} catch (e) {
print('Error updating profile: $e');
_showErrorDialog('Failed to update profile. Please try again.');
}
}
Я прикрепил фрагмент кода выше из того, что я пробовал. Мне нужно изменить его таким образом, чтобы он мог получить доступ к токену после успешного входа, который может помочь редактировать информацию.
Это должно помочь
final token = "your-backend-token";
final response = await http.put(
Uri.parse(url),
headers: {
"Content-Type": "application/json",
"User-Agent": "PostmanRuntime/7.28.4",
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive",
HttpHeaders.authorization: token,
},
);
Дополнительно можно сделать что-то вроде этого
class ApiHandler {
ApiHandler.instance(); // for instantiating request withou token
String? _token;
ApiHandler.tokenInstance() {
_token = getToken() ?? throw "No Token found";
// `getToken()` gets token from shared preferences or wherever you have stored.
}
// use this for public api requests
Map<String, String> get jsonHeaders = {
HttpHeaders.contentType: "application/json",
}
// use this for authorized api requests
Map<String, String> get tokenHeaders = {
HttpHeaders.contentType: "application/json",
HttpHeaders.authorization: _token,
}
// your other api request methods
}
Для хранения токена успешного входа в систему необходимо использовать пакет SharedPreferences:
final SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('token', '$<yourToken>');
потом, когда вам понадобится получить доступ к токену, просто вызовите:
final SharedPreferences prefs = await SharedPreferences.getInstance();
final String? token = prefs.getString('token');
Вы можете сделать это 3 способами:
- Создайте глобальную переменную и сохраните в ней токен .
- Используйте SharedPreferences для постоянного хранения токена
- Передайте токен в качестве параметра
. 3.1. Передача токена в качестве параметра конструктора
3.2. Передача маркера в качестве параметра функции
1. Глобальная переменная
Вы можете создать глобальный файл, содержащий эту переменную, и импортировать его везде, где к нему будут обращаться. Это гарантирует, что у вас будет один и тот же токен до тех пор, пока приложение не будет перезапущено. После перезапуска переменная снова обнулится
2. shared_preferences
Если вы используете плагин shared_preferences от flutter.dev, вы можете хранить данные постоянно на каждой машине.
Обратите внимание: при использовании этого метода вам нужно будет обработать асинхронную инициализацию SharedPreferences. После его инициализации вызовы чтения не будут асинхронными
final SharedPreferences prefs = await SharedPreferences.getInstance();
3. Передайте токен в качестве параметра
3.1. Параметр конструктора
Это будет немного хлопотно, и я бы не рекомендовал использовать это в вашем случае, но это все же вариант. Вот пример того, как это можно сделать с помощью StatefulWidget:
class ProfileOptions extends StatefulWidget {
const ProfileOptions({super.key, required this.id});
final String id;
@override
State<Product> createState() => _ProfileOptionsState();
}
class _ProfileOptionsState extends State<ProfileOptions> {
late String id;
@override
void initState() {
super.initState();
id = widget.id;
}}
@override
Widget build(BuildContext context) {
return Placeholder();
}
}
3.2. Параметр функции
Вы также можете передать токен в качестве параметра вашей функции. Это потребует от вас хранения и доступа к маркеру в том месте, откуда вы вызываете функцию (Таким образом, вам все равно придется выполнить 1, 2, 3.1 или хранить функцию в том же файле, что и переменную, и тогда вы сможете получить доступ к переменной из функции)
Future<void> updateProfile(String authToken) async {
// Your code
}