Главная страница
Навигация по странице:

  • 6.5 Вывод по разделу

  • Список использованных источников

  • ПРИЛОЖЕНИЕ Ж ПРИЛОЖЕНИЕ И ПРИЛОЖЕНИЕ К ПРИЛОЖЕНИЕ Л ПРИЛОЖЕНИЕ М

  • Программное средство Инвентаризация компьютеров. ПЗ_new. Руководство пользователя для разработанной системы. Пятый раздел приводит данные по информационной безопасности приложения


    Скачать 4.8 Mb.
    НазваниеРуководство пользователя для разработанной системы. Пятый раздел приводит данные по информационной безопасности приложения
    АнкорПрограммное средство Инвентаризация компьютеров
    Дата25.05.2023
    Размер4.8 Mb.
    Формат файлаdocx
    Имя файлаПЗ_new.docx
    ТипРуководство пользователя
    #1158409
    страница9 из 9
    1   2   3   4   5   6   7   8   9

    6.4 Межсайтовая подделка запросов

    Это такой тип атаки, при которой пользователь заходит на какой-либо вредоносный сайт, и этот сайт отправляет запросы на хороший сайт, на котором пользователь зарегистрирован, и который он недавно посещал. Может случится такое, что информации об авторизации на хорошем сайте все еще остается в куки. Тогда вполне может быть совершено и какое-то вредоносное скрытое действие.

    Атака может быть реализована путем включения ссылки или сценария в веб-страницу, с которой происходит переход на вредоносный сайт, считающий, что пользователь прошел авторизацию. Далее злоумышленник может получить авторизационные куки хорошего сайта и с ними отправить ему запрос, а тот проверив куки ничего не заподозрит.

    Риску подвергаются веб-приложения, которые выполняют действия, основанные на данных от доверяемых или авторизованных пользователей без требования от пользователя подтвердить конкретное действие. Пользователь, который авторизуется с помощью куки его веб-браузера может невольно направить HTTP-запрос на сайт, который доверяет этому пользователю, вызвав тем самым нежелательные действия.

    6.5 Вывод по разделу

    В разделе было уделено внимание анализу информационной безопасности разработанного кроссплатформенного приложения и некоторым методам защиты от уязвимостей.

    При разработке обязательно следует учитывать аспекты безопасности и проанализировать уязвимости, через которые возможна реализация угроз, и которые действуют на веб-приложение в виде отказов или снижения его работоспособности. Самые популярные виды атак и способы защиты от них разработанного веб-приложения были рассмотрены.

    В случае с личными данными пользователя не нужно беспокоиться о их защите, так как защиту предоставляет Firebase. Таким образом, можно сделать вывод о том, что личные данные пользователя максимально защищены в разработанном кроссплатформенном приложении и при его использовании ему не угрожает опасность вредоносных атак злоумышленников.

    Заключение

    В рамках дипломного проекта был разработан Интернет-сервис для инвентаризации компьютерного и офисного оборудования кафедры вуза.

    Для достижения поставленной цели решены следующие задачи:

    • проведен анализ аналогичных решений, выявлены их преимущества и недостатки;

    • определены основные функции разрабатываемого интернет-сервиса;

    • определены наиболее подходящие технологии для создания интернет-сервиса;

    • разработна серверная часть, включающая в себя основную логику осуществляющую хранение данных различных рабочих процессов в базе данных, обработку данных и использование;

    • проведено тестирование интернет-сервиса;

    • выполнено экономическое обоснование разработки.

    В результате проделанной работы разработан сервис, представляющий из себя сервер и кроссплатформенное клиентское приложение. Для достижения поставленной цели были реализованы следующие задачи:

    • разработана архитектура программного средства;

    • реализовано наличие нескольких ролей в программном средстве;

    • настроены сервисы HotChocolate и IdentityServer;

    • подключены сервисы и пакеты для выполнения поставленных задач.

    Так же было проведено экономическое обоснование.

    Результаты соответствуют заявленным требованиям. Проверена работоспособность модулей приложения и их связи с удаленными сервисами. Проведена проверка качества кода каждого компонента в соответствии с современными стандартами качества и рекомендациями к ним.

    Данное приложение будет интересно пользователям, желающим сэкономить собественное время, на ведении бухгалтерного учёта.

    Список использованных источников

    1 Наполи, Марко Л. Beginning Flutter: A Hands On Guide to App Development [Текст] – Wiley, 2019 – 453 c. – Дата доступа: 15.03.2020

    2 Firebase docs [Электронный ресурс] / электронный документ – Режим доступа: www.firebase.doc.org – Дата доступа: 02.04.2020

    3 Виндмилл, Э. Flutter in Action [Текст] – Manning, 2017 – 97 c. – Дата доступа 17.03.2020

    4 pub.dev [Электронный ресурс]: документация. – Режим доступа: www.pub.dev/documentation/ – Дата доступа: 05.03.2020.

    5 Замметти, Ф Practical Flutter [Текст] – Apress, 2019 – 295 c. – Дата доступа 07.03.2020

    6 Заккагино, К. Programming Flutter [Текст] – Pargprog, 2019 – 95 c. – Дата доступа: 15.03.2020

    7 Cross Site Scripting (XSS) [Электронный ресурс] / Owasp. – Режим доступа: https://owasp.org/www-community/attacks/xss/. – Дата доступа: 01.05.2020.

    8 Каштелян Т. В. Экономическое обоснование дипломных проектов/ Каштелян Т.В. – Минск: УО «Белорусский государственный технологический университет», 2012. – 88 с.

    9 Формирование цены разработки проекта [Электронный ресурс] / электронный документ – Режим доступа: https://it-hod.by/price#softdevelopment – Дата доступа: 08.03.2020

    10 Список стоимостей разработки мобильного приложения [Электронный ресурс] / электронный – Режим доступа: https://workspace.ru/minsk/mobile/ – Дата доступа: 08.03.2018
    ПРИЛОЖЕНИЕ А

    Исходный код auth_bloc.dart

    import 'dart:async';

    import 'package:bloc/bloc.dart';

    import 'package:equatable/equatable.dart';

    part 'auth_event.dart';

    part 'auth_state.dart';

    class AuthBloc extends Bloc {

    @override

    AuthState get initialState => AuthLoginState();

    @override

    Stream mapEventToState(

    AuthEvent event,

    ) async* {

    if (event is AuthLoginEvent) {

    yield AuthLoginState();

    } else if (event is AuthRegisterEvent) {

    yield AuthRegisterState();

    } else if (event is AuthStaffLoginEvent) {

    yield AuthStaffLoginState();

    }

    }

    }

    ПРИЛОЖЕНИЕ Б

    Исходный код tracking_page.dart

    import 'dart:async';

    import 'package:cloud_firestore/cloud_firestore.dart';

    import 'package:flutter/material.dart';

    import 'package:geolocator/geolocator.dart';

    import 'package:google_maps_flutter/google_maps_flutter.dart';

    import 'package:provider/provider.dart';

    import 'package:shared_preferences/shared_preferences.dart';

    class TrackingPage extends StatefulWidget {

    final DocumentSnapshot d;

    final String orderID;

    final bool client;

    TrackingPage({Key key, this.d, this.orderID, this.client = true})

    : super(key: key);

    @override

    _TrackingPageState createState() => _TrackingPageState();

    }

    class _TrackingPageState extends State {

    Completer _controller = Completer();

    LatLng location;

    bool staff = false;

    Timer trackUser;

    Timer trackCourier;

    Marker courierMarker;

    Stream courierStream;

    Set markers = Set();

    Marker toDeliver;

    void getCurrentPosition(BuildContext ctx) async {

    Geolocator g = Provider.of(ctx);

    Position p =

    await g.getCurrentPosition(desiredAccuracy: LocationAccuracy.best);

    setState(() {

    location = LatLng(p.latitude, p.longitude);

    });

    }

    void loadPreferences() async {

    SharedPreferences prefs = await SharedPreferences.getInstance();

    staff = prefs.getBool('staff');

    }

    @override

    Widget build(BuildContext context) {

    loadPreferences();

    getCurrentPosition(context);

    toDeliver = Marker(

    markerId: MarkerId('client'),

    position: LatLng(widget.d.data["deliverTo"].latitude,

    widget.d.data["deliverTo"].longitude),

    );

    markers.add(toDeliver);

    if (widget.client) {

    courierStream =

    Firestore.instance.document("orders/${widget.orderID}").snapshots();

    courierStream.listen((event) {

    courierMarker = Marker(

    markerId: MarkerId("courier"),

    position: LatLng(event.data["lastLocation"].latitude,

    event.data["lastLocation"].longitude),

    infoWindow: InfoWindow(title: 'Courier Location'),

    icon: BitmapDescriptor.defaultMarkerWithHue(

    BitmapDescriptor.hueBlue));

    markers.clear();

    markers.add(toDeliver);

    markers.add(courierMarker);

    });

    }

    return Scaffold(

    appBar: AppBar(),

    body: Container(

    child: Column(

    children: [

    Expanded(

    flex: 16,

    child: location != null &&

    (courierMarker != null || widget.client == false)

    ? GoogleMap(

    mapType: MapType.terrain,

    initialCameraPosition: CameraPosition(

    bearing: 0,

    target: location,

    tilt: 0,

    zoom: 15,

    ),

    onMapCreated: (controller) =>

    _controller.complete(controller),

    markers: markers,

    )

    : Center(

    child: CircularProgressIndicator(),

    ),

    ),

    Expanded(

    flex: widget.client ? 0 : 2,

    child: Container(

    child: widget.client ? null : Row(

    mainAxisAlignment: MainAxisAlignment.spaceEvenly,

    children: [

    RaisedButton(

    child: Text('Start tracking'),

    onPressed: trackUser != null ? null : () {

    trackUser =

    Timer.periodic(Duration(seconds: 15), (timer) {

    Geolocator()

    .getCurrentPosition(

    desiredAccuracy: LocationAccuracy.best,

    )

    .then((v) {

    courierMarker = Marker(

    markerId: MarkerId("courier"),

    position: LatLng(v.latitude, v.longitude),

    infoWindow:

    InfoWindow(title: 'Courier Location'),

    icon: BitmapDescriptor.defaultMarkerWithHue(

    BitmapDescriptor.hueBlue));

    markers.clear();

    markers.add(toDeliver);

    markers.add(courierMarker);

    Firestore.instance

    .document("orders/${widget.orderID}")

    .updateData({

    'lastLocation': GeoPoint(v.latitude, v.longitude)

    });

    });

    });

    },

    ),

    RaisedButton(

    child: Text('Stop tracking'),

    onPressed: trackUser != null

    ? () {

    trackUser.cancel();

    trackUser = null;

    }

    : null,

    ),

    RaisedButton(

    child: Text('Finish Delivery'),

    onPressed: () {

    Firestore.instance.document("orders/${widget.orderID}").updateData({

    'delivered': true

    });},)],),),)],),),);}}

    ПРИЛОЖЕНИЕ В

    Исходный код main.dart

    import 'package:auto_route/auto_route.dart';

    import 'package:firebase_storage/firebase_storage.dart';

    import 'package:flutter/material.dart';

    import 'package:geolocator/geolocator.dart';

    import 'package:provider/provider.dart';

    import 'package:flutter_bloc/flutter_bloc.dart';

    import 'package:firebase_auth/firebase_auth.dart';

    import 'package:firebase_messaging/firebase_messaging.dart';

    import 'package:cloud_firestore/cloud_firestore.dart';

    import 'package:meal_kit_delivery/bloc/auth_bloc.dart';

    import 'package:meal_kit_delivery/routes/router.gr.dart';

    void main() => runApp(MyApp());

    class MyApp extends StatelessWidget {

    @override

    Widget build(BuildContext context) {

    return MultiProvider(

    providers: [

    Provider(create: (_) => FirebaseAuth.instance),

    Provider(create: (_) => Firestore.instance),

    Provider(create: (_) => FirebaseStorage.instance),

    Provider(create: (_) => Geolocator()),

    Provider(create: (_) => FirebaseMessaging()),

    BlocProvider(create: (_) => AuthBloc())

    ],

    child: MaterialApp(

    debugShowCheckedModeBanner: false,

    title: 'Material App',

    theme: ThemeData.light().copyWith(

    primaryColor: Colors.deepOrange[700],

    accentColor: Colors.deepOrangeAccent,

    ),

    builder: ExtendedNavigator(router: Router())

    ),);}}

    ПРИЛОЖЕНИЕ Г

    Исходный код paymet_page.dart

    import 'package:auto_route/auto_route.dart';

    import 'package:cloud_firestore/cloud_firestore.dart';

    import 'package:firebase_auth/firebase_auth.dart';

    import 'package:flutter/material.dart';

    import 'package:geolocator/geolocator.dart';

    import 'package:intl/intl.dart';

    import 'package:meal_kit_delivery/models/meal_model.dart';

    import 'package:meal_kit_delivery/models/ingredients_model.dart';

    import 'package:provider/provider.dart';

    class PaymentPage extends StatefulWidget {

    final int count;

    final Meal meal;

    final Ingredients ingredients;

    PaymentPage({Key key, this.count, this.meal, this.ingredients})

    : super(key: key);

    @override

    _PaymentPageState createState() => _PaymentPageState();

    }

    class _PaymentPageState extends State
    {


    FirebaseUser current;

    @override

    void initState() {

    FirebaseAuth fba = FirebaseAuth.instance;

    fba.currentUser().then((value) => setState(() {

    current = value;

    }));

    super.initState();

    }

    @override

    Widget build(BuildContext context) {

    return Scaffold(

    appBar: AppBar(),

    body: Container(

    child: current == null

    ? Center(

    child: CircularProgressIndicator(),

    )

    : Column(

    children: [

    Expanded(

    flex: 9,

    child: Container(

    padding: EdgeInsets.all(16),

    child: Container(

    decoration: BoxDecoration(

    border: Border.all(

    color: Colors.black,

    width: 3,

    ),

    ),

    padding: EdgeInsets.all(16),

    child: Column(

    children: [

    Expanded(

    flex: 1,

    child: Row(

    children: [

    Icon(

    Icons.shopping_cart,

    size: 30,

    ),

    Text(

    'Order Summary',

    style: TextStyle(fontSize: 18),

    )],),),

    Expanded(

    flex: 1,

    child: Row(

    children: [

    Text(

    'Items in order: ${widget.count}',

    style: TextStyle(fontSize: 16),

    )

    ],

    ),

    ),

    Expanded(

    flex: 6,

    child: Container(

    child: ListView.separated(

    itemCount: widget.count,

    separatorBuilder: (_, idx) =>

    SizedBox(height: 5),

    itemBuilder: (_, idx) => Card(

    child: ListTile(

    title: Text(widget.meal.name),

    subtitle: Text("Total mass: ${[

    ...widget.ingredients.grain.entries.map(

    (e) => int.parse(

    e.value.split(' ')[0])),

    ...widget.ingredients.spice.entries.map(

    (e) => int.parse(

    e.value.split(' ')[0])),

    ...widget.ingredients.fruit.entries.map(

    (e) => int.parse(

    e.value.split(' ')[0])),

    ...widget.ingredients.vegetable.entries

    .map((e) => int.parse(

    e.value.split(' ')[0])),

    ...widget.ingredients.meat.entries.map(

    (e) => int.parse(

    e.value.split(' ')[0]))

    ].reduce((n, next) => n + next)} g"),

    trailing: Text("${widget.meal.cost} BYN"),

    ),),),),),

    Expanded(

    flex: 1,

    child: Container(

    child: Row(

    mainAxisAlignment: MainAxisAlignment.end,

    children: [

    Text(

    "Sub total: ${NumberFormat('###.##', "en_US").format(widget.meal.cost * widget.count)} BYN",

    style: TextStyle(fontSize: 24),

    )],),),)],),),),),

    Expanded(

    flex: 5,

    child: Row(

    children: [

    Expanded(

    flex: 5,

    child: Container(

    child: Column(

    children: [

    Text(

    'Order to your position',

    style: TextStyle(fontSize: 16),

    ),

    Padding(

    padding: const EdgeInsets.only(top: 16.0),

    child: RaisedButton(

    child: Text('Order'),

    color: Theme.of(context).accentColor,

    onPressed: () {

    Geolocator g = Provider.of(

    context,

    listen: false);

    Firestore fs = Provider.of(

    context,

    listen: false);

    g.getCurrentPosition().then((p) {

    fs.collection("orders").add({

    'count': widget.count,

    'meal': widget.meal.documentID,

    'user': current.uid,

    'deliverTo':

    GeoPoint(p.latitude, p.longitude),

    'total':

    widget.count * widget.meal.cost,

    'delivered': false,

    'taken': false

    });

    });

    ExtendedNavigator.of(context).pop();

    },),)],),),),

    Expanded(

    flex: 7,

    child: Container(

    child: Column(

    children: [

    Expanded(

    flex: 1,

    child: Text(

    'Or select from existing',

    style: TextStyle(fontSize: 16),

    )),

    Expanded(

    flex: 4,

    child: StreamBuilder(

    stream: Provider.of(context)

    .collection("addresses")

    .where("user", isEqualTo: current.uid)

    .snapshots(),

    builder: (ctx, snapshot) {

    switch (snapshot.connectionState) {

    case ConnectionState.waiting:

    return Center(

    child: CircularProgressIndicator(),

    );

    default:

    if (snapshot.hasData &&

    !snapshot

    .data.documents.isEmpty) {

    return ListView.builder(

    itemCount: snapshot

    .data

    .documents

    .first

    .data["addresses"]

    .length,

    itemBuilder: (_, idx) => ListTile(

    title: Text(snapshot

    .data

    .documents

    .first

    .data["addresses"][idx]),

    trailing:

    Icon(Icons.location_on),

    onTap: () {

    Firestore fs =

    Provider.of(

    context,

    listen: false);

    Provider.of(

    context,

    listen: false)

    .placemarkFromAddress(

    snapshot

    .data

    .documents

    .first

    .data["addresses"][idx])

    .then((value) {

    fs

    .collection("orders")

    .add({

    'count': widget.count,

    'meal': widget

    .meal.documentID,

    'user': current.uid,

    'deliverTo': GeoPoint(

    value.first.position

    .latitude,

    value.first.position

    .longitude),

    'total': widget.count *

    widget.meal.cost,

    'delivered': false,

    'taken': false

    });

    ExtendedNavigator.of(

    context)

    .pop();

    });}),);

    } else {

    return Center(

    child: Text("No addresses"),

    );}}},),)],),),)],),)],),),);}}

    ПРИЛОЖЕНИЕ Д

    Исходный код addresses_page.dart

    import 'package:cloud_firestore/cloud_firestore.dart';

    import 'package:firebase_auth/firebase_auth.dart';

    import 'package:flutter/material.dart';

    import 'package:meal_kit_delivery/elements/side_drawer.dart';

    import 'package:provider/provider.dart';

    import 'package:rxdart/rxdart.dart';

    class AddressesPage extends StatefulWidget {

    AddressesPage({Key key}) : super(key: key);

    @override

    _AddressesPageState createState() => _AddressesPageState();

    }

    class _AddressesPageState extends State {

    FirebaseUser current;

    String addressID;

    TextEditingController _address = TextEditingController();

    @override

    void initState() {

    FirebaseAuth fba = FirebaseAuth.instance;

    fba.currentUser().then((value) => setState(() {

    current = value;

    }));

    super.initState();

    }

    @override

    Widget build(BuildContext context) {

    return Scaffold(

    drawer: SideDrawer(),

    appBar: AppBar(),

    body: current == null

    ? Center(

    child: CircularProgressIndicator(),

    )

    : Container(

    padding: EdgeInsets.all(16),

    child: StreamBuilder(

    stream: Provider.of(context)

    .collection("addresses")

    .where("user", isEqualTo: current.uid)

    .snapshots(),

    builder: (_, snap) {

    switch (snap.connectionState) {

    case ConnectionState.waiting:

    return Center(

    child: CircularProgressIndicator(),

    );

    default:

    if (snap.hasData && !snap.data.documents.isEmpty) {

    addressID = snap.data.documents.first.documentID;

    print(addressID);

    return ListView.builder(

    itemCount: snap

    .data.documents.first.data["addresses"].length,

    itemBuilder: (_, idx) => ListTile(

    title: Text(snap

    .data.documents.first.data["addresses"][idx]),

    trailing: Icon(Icons.location_on),

    onLongPress: () => Firestore.instance

    .document(

    "addresses/${snap.data.documents.first.documentID}")

    .updateData({

    "addresses": FieldValue.arrayRemove([snap

    .data.documents.first.data["addresses"][idx]])

    }),

    ),

    );

    } else {

    Provider.of(context)

    .collection("addresses")

    .add({

    "user": current.uid,

    "addresses": [],

    }).then((ref) => addressID = ref.documentID);

    return Center(child: Text('No addresses'));

    }

    }

    },

    ),

    ),

    floatingActionButton: FloatingActionButton(

    child: Icon(Icons.add),

    backgroundColor: Theme.of(context).accentColor,

    onPressed: () => showDialog(

    context: context,

    barrierDismissible: true,

    builder: (ctx) => AlertDialog(

    contentPadding: EdgeInsets.all(8),

    content: Row(

    children: [

    Expanded(

    child: TextField(

    controller: _address,

    autofocus: true,

    decoration: InputDecoration(labelText: 'Address'),

    ),

    )

    ],

    ),

    actions: [

    FlatButton(

    child: Text('Dismiss'),

    onPressed: () => Navigator.pop(ctx),

    textColor: Theme.of(context).primaryColor,

    ),

    FlatButton(

    child: Text('Accept'),

    textColor: Theme.of(context).primaryColor,

    onPressed: () {

    Provider.of(ctx, listen: false)

    .document("addresses/$addressID")

    .updateData({

    "addresses": FieldValue.arrayUnion([_address.text])

    });

    _address.text = '';

    Navigator.pop(ctx);

    },)],),),),);}}

    ПРИЛОЖЕНИЕ Е

    Исходный код deliveries_page.dart

    import 'package:cloud_firestore/cloud_firestore.dart';

    import 'package:firebase_auth/firebase_auth.dart';

    import 'package:flutter/material.dart';

    import 'package:meal_kit_delivery/elements/side_drawer.dart';

    import 'package:meal_kit_delivery/elements/delivery_item.dart';

    import 'package:meal_kit_delivery/elements/order_item.dart';

    import 'package:provider/provider.dart';

    class DeliveriesPage extends StatefulWidget {

    DeliveriesPage({Key key}) : super(key: key);

    @override

    _DeliveriesPageState createState() => _DeliveriesPageState();

    }

    class _DeliveriesPageState extends State {

    FirebaseUser current;

    @override

    void initState() {

    FirebaseAuth fba = FirebaseAuth.instance;

    fba.currentUser().then((value) => setState(() {

    current = value;

    }));

    super.initState();

    }

    @override

    Widget build(BuildContext context) {

    return DefaultTabController(

    length: 2,

    child: Scaffold(

    drawer: SideDrawer(),

    appBar: AppBar(

    bottom: TabBar(

    indicatorColor: Theme.of(context).accentColor,

    tabs: [

    Tab(text: 'Deliveries'),

    Tab(text: 'Orders'),

    ],

    ),

    ),

    body: current == null

    ? Center(

    child: CircularProgressIndicator(),

    )

    : Container(

    padding: EdgeInsets.all(24),

    child: Center(

    child: TabBarView(

    children: [

    StreamBuilder(

    stream: Provider.of(context)

    .collection("orders")

    .where("user", isEqualTo: current.uid)

    .where("delivered", isEqualTo: false)

    .snapshots(),

    builder: (_, snapshot) {

    switch (snapshot.connectionState) {

    case ConnectionState.waiting:

    return Center(

    child: CircularProgressIndicator(),

    );

    default:

    return ListView.builder(

    itemCount: snapshot.data.documents.length,

    itemBuilder: (_, idx) {

    return DeliveryItem(

    isTracking: true,

    d: snapshot.data.documents[idx]);

    },

    );

    }

    },

    ),

    StreamBuilder(

    stream: Provider.of(context)

    .collection("orders")

    .where("user", isEqualTo: current.uid)

    .where("delivered", isEqualTo: true)

    .snapshots(),

    builder: (_, snapshot) {

    switch (snapshot.connectionState) {

    case ConnectionState.waiting:

    return Center(

    child: CircularProgressIndicator(),

    );

    default:

    return ListView.builder(

    itemCount: snapshot.data.documents.length,

    itemBuilder: (_, idx) {

    return OrderItem(

    d: snapshot.data.documents[idx]);

    },);}},),],),),),),);}}

    ПРИЛОЖЕНИЕ Ж

    ПРИЛОЖЕНИЕ И

    ПРИЛОЖЕНИЕ К

    ПРИЛОЖЕНИЕ Л

    ПРИЛОЖЕНИЕ М
    1   2   3   4   5   6   7   8   9


    написать администратору сайта